簡體   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