2

I would like to do something like this:

public async Task MyMethod()
{
    // Do some preparation

    await Parallel.ForEachAsync(0, count, i => { // Do some work //});

    // do some finalization
}

However, I did not find an elegant way of doing so. I thought of two ways, but they are sub-optimal:

  1. The only thing I thought about is manually partitioning the range, creating tasks, and then using Task.WhenAll.
  2. Using the following code Task.Factory.StartNew(() => Parallel.For(...));.
    The problem is that it "wastes" a thread on the asynchronous task.
  3. Using TPL Dataflow's ActionBlock, and posting the integers one by one. The drawback is that it does not partition the range in a smart way like Parallel.For does, and works on each iteration one by one.
  4. Manually using a Partitioner with Partitioner.Create, but it is less elegant. I want the framework to do intelligent partitioning for me.
Alex Shtoff
  • 2,520
  • 1
  • 25
  • 53
  • Is your forEach operation IO or cpu bound? – Big Daddy Sep 02 '16 at 16:55
  • I believe http://stackoverflow.com/questions/11564506/nesting-await-in-parallell-foreach (used as duplicate) provides all sensible ways to mix `async` and `Parallel.ForEach`. If that's does not answer your particular case - make sure to [edit] your post explaining why so it can be re-opened. – Alexei Levenkov Sep 02 '16 at 17:13
  • Edited. Please re-consider. – Alex Shtoff Sep 02 '16 at 17:15

1 Answers1

3

You have a regular synchronous parallel loop that you'd like to invoke asynchronously (presumably to move it off the UI thread).

You can do this the same way you'd move any other CPU-bound work off the UI thread: using Task.Run:

public async Task MyMethod()
{
  // Do some preparation

  await Task.Run(() => Parallel.ForEach(0, count, i => { /* Do some work */ }));

  // do some finalization
}

There is no thread "wasted" because Parallel.ForEach will use the calling thread as one of its worker threads.

(This is recipe 7.4 "Async Wrappers for Parallel Code" in my book).

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810