繁体   English   中英

等效的C#ActionBlock收集结果

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM