.net 你在使用并行扩展吗?
我希望这不是对stackoverflow的滥用;最近我在这里看到了一些关于并行扩展的好问题,这引起了我的兴趣 我的问题: 您是否正在使用并行扩展,如果是,如何使用 我叫Stephen Toub,是微软并行计算平台团队的成员。我们是负责并行扩展的小组。我总是很感兴趣地听到开发人员如何利用并行扩展(例如Parallel.For、PLINQ、concurrentdirectionary等)、您的积极体验、消极体验、对未来的功能要求等等。.net 你在使用并行扩展吗?,.net,parallel-processing,task,task-parallel-library,plinq,.net,Parallel Processing,Task,Task Parallel Library,Plinq,我希望这不是对stackoverflow的滥用;最近我在这里看到了一些关于并行扩展的好问题,这引起了我的兴趣 我的问题: 您是否正在使用并行扩展,如果是,如何使用 我叫Stephen Toub,是微软并行计算平台团队的成员。我们是负责并行扩展的小组。我总是很感兴趣地听到开发人员如何利用并行扩展(例如Parallel.For、PLINQ、concurrentdirectionary等)、您的积极体验、消极体验、对未来的功能要求等等。 如果您愿意分享这些信息,请在这里作为对这个问题的回答,或者通过电
如果您愿意分享这些信息,请在这里作为对这个问题的回答,或者通过电子邮件(microsoft.com的
stoub
)私下告诉我
我非常期待你的来信
提前谢谢 我一直在我的项目中使用它。我有一个基于MSBuild的DSL编译管道,单阶段类型是多对多阶段。M:M阶段使用.AsParallel.ForAll(…) 以下是:
受保护的密封覆盖IEnumerable进程()
{
if(this.Input.Count()>1)
{
这个。输入
.天冬酰胺()
.ForAll(这个过程);
}
else if(this.Input.Any())
{
this.Process(this.Input.Single());
}
返回此.Input.ToArray();
}
我正在使用TPL进行嵌套的并行.ForEach
调用。因为我从这些调用中访问字典,所以我必须使用concurrentdirectionary
。虽然很好,但我有几个问题:
中的代理没有做很多工作,因此我没有获得多少并行性。系统似乎花费了大部分时间连接线程。如果有一种方法可以找出为什么并发性没有得到改善并加以改进,那就太好了ForEach
- 内部
迭代超过了ForEach
实例,如果我没有添加枚举器缓存,这将导致系统花费大量时间为字典使用枚举器ConcurrentDictionary
- 我的许多
实例实际上都是集合,但是没有ConcurrentDictionary
,因此我必须用ConcurrentSet
实现自己的实例ConcurrentDictionary
不支持对象初始化语法,所以我不能说ConcurrentDictionary
这也意味着我不能将var dict=newConcurrentDictionary{{'A',65}
文本分配给类成员ConcurrentDictionary
- 在某些地方,我必须在
中查找一个键,并调用一个昂贵的函数来创建一个不存在的值。如果有一个重载ConcurrentDictionary
,它接受一个GetOrAdd
,这样只有在键不存在时才能计算值,那就更好了。这可以用addValueFactory
来模拟,但这会增加每次查找的额外委托调用的开销.AddOrUpdate(key,addValueFactory,(k,v)=>v)
private static readonly char[] delimiters = { ' ', '.', ',', ';', '\'', '-', ':', '!', '?', '(', ')', '<', '>', '=', '*', '/', '[', ']', '{', '}', '\\', '"', '\r', '\n' };
private static readonly Func<string, string> theWord = Word;
private static readonly Func<IGrouping<string, string>, KeyValuePair<string, int>> theNewWordCount = NewWordCount;
private static readonly Func<KeyValuePair<string, int>, int> theCount = Count;
private static void Main(string[] args)
{
foreach (var wordCount in File.ReadAllText(args.Length > 0 ? args[0] : @"C:\DEV\CountUniqueWords\CountUniqueWords\Program.cs")
.Split(delimiters, StringSplitOptions.RemoveEmptyEntries)
.AsParallel()
.GroupBy(theWord, StringComparer.OrdinalIgnoreCase)
.Select(theNewWordCount)
.OrderByDescending(theCount))
{
Console.WriteLine(
"Word: \""
+ wordCount.Key
+ "\" Count: "
+ wordCount.Value);
}
Console.ReadLine();
}
private static string Word(string word)
{
return word;
}
private static KeyValuePair<string, int> NewWordCount(IGrouping<string, string> wordCount)
{
return new KeyValuePair<string, int>(
wordCount.Key,
wordCount.Count());
}
private static int Count(KeyValuePair<string, int> wordCount)
{
return wordCount.Value;
}
private static readonly char[]分隔符={'、'.'、'.'、';'、'\''.-'、':'、'!'、'?'、'('、')、''''='、'*'、'/'、'['、'.']、'{'、'}'、'\\'、''.'、'\r'、'\n'};
私有静态只读Func theWord=Word;
私有静态只读函数theNewWordCount=NewWordCount;
私有静态只读Func theCount=Count;
私有静态void Main(字符串[]args)
{
foreach(文件.ReadAllText中的var wordCount(args.Length>0?args[0]:@“C:\DEV\CountUniqueWords\CountUniqueWords\Program.cs”)
.Split(分隔符、StringSplitOptions.RemoveEmptyEntries)
.天冬酰胺()
.GroupBy(单词、StringComparer.OrdinalIgnoreCase)
。选择(新建或计数)
.OrderByDescending(计数))
{
控制台写入线(
“单词:\”
+wordCount.Key
+“\”计数:
+wordCount.Value);
}
Console.ReadLine();
}
专用静态字符串字(字符串字)
{
返回词;
}
私有静态KeyValuePair NewWordCount(iGroup wordCount)
{
返回新的KeyValuePair(
wordCount.Key,
Count.Count());
}
私有静态整数计数(KeyValuePair字计数)
{
返回wordCount.Value;
}
我们没有广泛使用它,但它确实派上了用场
通过在Parallel.Invoke()
调用中包装一些更耗时的步骤,我能够将一些运行时间较长的单元测试的运行时间减少到原来的1/3左右
我也喜欢使用并行库来测试线程安全性。我发现并报告了Ninject的几个线程问题,代码如下:
var repositoryTypes = from a in CoreAssemblies
from t in a.GetTypes()
where t.Name.EndsWith("Repository")
select t;
repositoryTypes.ToList().AsParallel().ForAll(
repositoryType => _kernel.Get(repositoryType));
在我们实际的生产代码中,我们使用一些并行扩展来运行一些集成操作,这些操作应该每隔几分钟运行一次,主要包括从web服务中提取数据。由于web连接固有的高延迟,这特别利用了并行性,并允许我们的所有作业在运行之前完成它们应该会再次启动。我使用的ConcurrentDictionary存储了1亿多个项目。我的应用程序当时使用了大约8 GB的内存。ConcurrentDictionary随后决定它要在另一个Add上增长。它显然要增长很多(一些内部prima算法)因为内存不足。这是在x64上,内存为32GB 所以我想要一个bo
var repositoryTypes = from a in CoreAssemblies
from t in a.GetTypes()
where t.Name.EndsWith("Repository")
select t;
repositoryTypes.ToList().AsParallel().ForAll(
repositoryType => _kernel.Get(repositoryType));