[英]C# ActionBlock Equivalent that collects results
我目前正在使用ActionBlock处理串行启动的异步作业。 它非常适合处理发布到它的每个项目,但是无法收集每个作业的结果列表。
我可以使用什么以线程安全的方式收集工作结果?
我的代码目前是这样的:
var actionBlock = new ActionBlock<int> (async i => await Process(i));
for(int i = 0; i < 100; i++)
{
actionBlock.Post(i);
}
actionBlock.Complete();
await actionBlock.Completion;
我尝试使用TransformBlock代替,但是在等待完成时它会无限期地挂起。 完成状态为“ WaitingForActivation”。
我使用TransformBlock的代码是这样的:
var transformBlock = new TransformBlock<int, string> (async i => await Process(i));
for(int i = 0; i < 100; i++)
{
actionBlock.Post(i);
}
actionBlock.Complete();
await actionBlock.Completion;
transformBlock.TryReceiveAll(out IList<string> strings);
事实证明,ConcurrentBag是答案
var bag = new ConcurrentBag<string>();
var actionBlock = new ActionBlock<int> (async i =>
bag.Add(await Process(i))
);
for(int i = 0; i < 100; i++)
{
actionBlock.Post(i);
}
actionBlock.Complete();
await actionBlock.Completion;
现在,“ bag”具有所有结果,并且可以作为IEnumerable访问。
我实际上最终使用的代码使用了Parallel.ForEach而不是ActionBlock。
Parallel.ForEach
(
inputData,
i => bag.Add(await Process(i))
);
这要简单得多,但看起来对性能同样有好处,并且仍然可以选择限制并行度等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.