Sni*_*ave 43 .net c# parallel-processing multithreading
寻找有关利用AsParallel()或Parallel.ForEach()加快这一点的一些建议.
请参阅下面的方法(本例中简化/标准化).
它需要一个像"US,FR,APAC"这样的列表,其中"APAC"是50个其他"US,FR,JP,IT,GB"等的别名.该方法应采用"US,FR,APAC",并将其转换为"US","FR"列表以及"APAC"中的所有国家/地区.
private IEnumerable<string> Countries (string[] countriesAndAliases)
{
var countries = new List<string>();
foreach (var countryOrAlias in countriesAndAliases)
{
if (IsCountryNotAlias(countryOrAlias))
{
countries.Add(countryOrAlias);
}
else
{
foreach (var aliasCountry in AliasCountryLists[countryOrAlias])
{
countries.Add(aliasCountry);
}
}
}
return countries.Distinct();
}
Run Code Online (Sandbox Code Playgroud)
是否将其并行化为将其更改为以下内容?使用AsParallel()比这更细微吗?我应该使用Parallel.ForEach()而不是foreach?并行化foreach循环时我应该使用哪些经验法则?
private IEnumerable<string> Countries (string[] countriesAndAliases)
{
var countries = new List<string>();
foreach (var countryOrAlias in countriesAndAliases.AsParallel())
{
if (IsCountryNotAlias(countryOrAlias))
{
countries.Add(countryOrAlias);
}
else
{
foreach (var aliasCountry in AliasCountryLists[countryOrAlias].AsParallel())
{
countries.Add(aliasCountry);
}
}
}
return countries.Distinct();
}
Run Code Online (Sandbox Code Playgroud)
And*_*rey 69
几点.
写作只是countriesAndAliases.AsParallel()没用.AsParallel()成为并行执行后的Linq查询的一部分.部分是空的,所以根本没用.
通常你应该repace foreach用Parallel.ForEach().但要注意不是线程安全的代码!你拥有了它.你不能把它包装成foreach因为它List<T>.Add本身不是线程安全的.
所以你应该这样做(对不起,我没有测试,但它编译):
return countriesAndAliases
.AsParallel()
.SelectMany(s =>
IsCountryNotAlias(s)
? Enumerable.Repeat(s,1)
: AliasCountryLists[s]
).Distinct();
Run Code Online (Sandbox Code Playgroud)
编辑:
你必须确定另外两件事:
IsCountryNotAlias必须是线程安全的.如果它是纯粹的功能会更好.AliasCountryLists,因为字典不是线程安全的.或者使用ConcurrentDictionary来确定.有用的链接,可以帮助您:
并行编程模式:使用.NET Framework理解和应用并行模式4
我什么时候应该使用Parallel.ForEach?我什么时候应该使用PLINQ?
PS:正如您所看到的那样,新的并行功能并不像它们看起来那样明显(和感觉).
Ree*_*sey 13
使用AsParallel()时,您需要确保您的身体是线程安全的.不幸的是,上面的代码不起作用. List<T>不是线程安全的,所以你的添加AsParallel()会导致竞争条件.
但是,如果您将集合切换为使用System.Collections.Concurrent中的集合,例如ConcurrentBag<T>,上述代码很可能会起作用.
| 归档时间: |
|
| 查看次数: |
47611 次 |
| 最近记录: |