TPL Dataflow and async/await vs CCR - part 3

While you could use TPL data-flow for scatter/gather patterns in much the same way as CCR async/await is actually enough for you once again. The only thing you need to do is to create a number of tasks and then wait for them all either by using the Task.WaitAll method (or Task.WaitAny if you're only interested in the first result) but if you have a short constant list of tasks to wait for I would just wait for them with the await keyword like this:

  1: public static async Task<int> FibonacciAsync(int n)
 2: {
 3:     if (n <= 1)
 4:     {
 5:         return n;
 6:     }
 7:     var n1 = FibonacciAsync(n - 1);
 8:     var n2 = FibonacciAsync(n - 2);
 9:     return await n1 + await n2;
 10: }

Remember a common pattern in CCR where you want to scatter/gather on a large number of tasks but wait for all success or first failure? While this also can be achieved with TPL data-flow async/await may be enough depending on how you report errors. If you use exceptions to report errors your scatter/gather will "continue on first failure" if you throw an exception when error occurs. Only in the case where the error is returned TPL data-flows would be a suitable solution and it would be very CCRish in how it would be done (i.e. post back exceptions etc).

Preventive comment: Technically the code above will execute synchronously (since no threads are started nor real async methods are being called), but that is not important. I wanted to show a simple "scatter/gather" pattern by first calling a number of async functions and then awaiting the results as needed.