我有此代码:
var data = new BufferBlock<int>(new DataflowBlockOptions { BoundedCapacity = 1 }); var action = new ActionBlock<int>(async id => { Console.WriteLine("[{0:T}] #{1}: Start", DateTime.Now, id); await Task.Delay(1000); Console.WriteLine("[{0:T}] #{1}: End", DateTime.Now, id); }, new ExecutionDataflowBlockOptions { BoundedCapacity = 1, MaxDegreeOfParallelism = -1 }); data.LinkTo(action, new DataflowLinkOptions { PropagateCompletion = true }); for (var id = 1; id <= 3; id++) { Console.WriteLine("[{0:T}] Sending {1}", DateTime.Now, id); data.SendAsync(id).Wait(); Console.WriteLine("[{0:T}] Sending {1} complete", DateTime.Now, id); } data.Complete(); Task.WhenAll(data.Completion, action.Completion).Wait();这段代码为我提供了此输出:
And this code gets me this output:
[22:31:22] Sending 1 [22:31:22] Sending 1 complete [22:31:22] Sending 2 [22:31:22] #1: Start [22:31:22] Sending 2 complete [22:31:22] Sending 3 [22:31:23] #1: End [22:31:23] #2: Start [22:31:23] Sending 3 complete [22:31:24] #2: End [22:31:24] #3: Start [22:31:25] #3: EndActionBlock为什么具有不受限制的DOP不能并行工作?
Why isn't ActionBlock working in parallel even though it has an unbounded DOP?
推荐答案您的ActionBlock似乎具有有限的并行度的原因是因为它的BoundedCapacity为1.BoundedCapacity(不同于)包括当前正在处理的项目.这很容易证明:
The reason your ActionBlock seems to be have a limited degree of parallelism is because it has a BoundedCapacity of 1. BoundedCapacity (unlike InputCount) includes the item being processed at the moment. This can be easily demonstrated:
var block = new ActionBlock<int>(_ => Task.Delay(-1), new ExecutionDataflowBlockOptions { BoundedCapacity = 1, MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded }); await block.SendAsync(4); // Adds a new item await block.SendAsync(4); // Blocks forever这意味着当您设置MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded时,该块不能同时接受多个项目,因此实际上限制了您的并行度.
That means that while you set MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded the block can't accept more than a single item at the time and so practically limiting your degree of parallelism.
您可以通过设置更大的BoundedCapacity来解决此问题:
You can fix that by setting a larger BoundedCapacity:
var action = new ActionBlock<int>(async id => { Console.WriteLine("[{0:T}] #{1}: Start", DateTime.Now, id); await Task.Delay(1000); Console.WriteLine("[{0:T}] #{1}: End", DateTime.Now, id); }, new ExecutionDataflowBlockOptions { BoundedCapacity = 10, MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded });更多推荐
具有BoundedCapacity的BufferBlock和ActionBlock不使用最大DOP
发布评论