【发布时间】:2020-07-01 03:48:49
【问题描述】:
当TransformBlock 具有非无限的MaxDegreeOfParallelism > 1 和BoundedCapacity 时,为什么尽管输入队列中有容量,但在有一个长时间运行的任务时它会推迟接收更多消息?
采取以下控制台应用程序。它使用MaxDegreeOfParallelism = 5 和BoundedCapacity = 5 创建一个TransformBlock,然后向它提供100 条消息。当块处理消息x == 50 时,它会将该任务延迟 10 秒。
TransformBlock<int, string> DoSomething = new TransformBlock<int, string>(async (x) => {
if (x == 50)
{
Console.WriteLine("x == 50 reached, delaying for 10 seconds.");
await Task.Delay(10000);
}
Console.WriteLine($"processed message {x}");
return x.ToString();
}, new ExecutionDataflowBlockOptions { BoundedCapacity = 5, MaxDegreeOfParallelism = 5 });
DoSomething.LinkTo(DataflowBlock.NullTarget<string>()); // ensure we empty the transform block
for (int i = 0; i < 100; i++)
{
Stopwatch blockedTime = Stopwatch.StartNew();
await DoSomething.SendAsync(i).ConfigureAwait(false);
blockedTime.Stop();
Console.WriteLine($"Submitted {i}\tBlocked for {blockedTime.ElapsedMilliseconds}ms.");
}
DoSomething.Complete();
await DoSomething.Completion;
Console.WriteLine("Completed.");
Console.ReadKey();
结果显示消息 50-54 都被区块接收。消息 51-54 已完成,然后控制台窗口在 10 秒内没有显示任何输出,然后才显示消息 50 已完成并且块能够接收到消息 55。
...
Submitted 50 Blocked for 0ms.
Submitted 51 Blocked for 0ms.
processed message 51
Submitted 52 Blocked for 0ms.
x == 50 reached, delaying for 10 seconds.
processed message 52
processed message 53
Submitted 53 Blocked for 0ms.
Submitted 54 Blocked for 0ms.
processed message 54 // when run, 10 seconds pause happens after displaying this line
processed message 50
processed message 55
Submitted 55 Blocked for 9998ms.
...
为什么Transform Block 不继续将块填充到 Bounded Capacity 5,而使用其他 4 度的并行度继续处理消息?
ActionBlock 不显示这些症状并继续处理其他可用并行线路上的消息。
无限容量TransformBlock 也不会显示这些症状。
【问题讨论】:
标签: c# .net tpl-dataflow