Search code examples
c#.nettask-parallel-libraryasync-awaittpl-dataflow

What is the difference between specifying Action directly or Task-Generator with TPL dataflow ActionBlock?


What is the difference between specifying Action directly or Func<Task> with .NET TPL Dataflow ActionBlock?

Direct Action:

new ActionBlock<Message[]>(x => DoSomething(x))

Task:

new ActionBlock<Message[]>(x => Task.Run(() => DoSomething(x)))

I'm trying to understand the differences in regard to parallel execution (MaxDegreeOfParallelism > 1).


Solution

  • TPL Dataflow supports both async and synchronous delegates so there's no difference regarding the degree of parallelism. It "knows" to await the returned task that represents the item's asynchronous execution and not continue on to the next item. In both cases no more than MaxDegreeOfParallelism items would be processed concurrently. The first option would use the synchronous delegate (i.e. Action) while the second the async one (i.e Func<Task>).

    However using Task.Run would take up an extra thread for each item's execution only to release it back to the thread pool after it's done. It's offloading work to another thread with no reason. So don't use it, it adds no value.