await in Parallel.foreach

16,150

Solution 1

Late to answer, but it looks like you're trying to perform CPU-bound work in parallel, as opposed to performing I/O-bound work asynchronously. Parallel.ForEach is taking care of your parallelism, so no need for Task.Run, and async/await are gaining you nothing here. I'd suggest removing those bits from method2, so the whole thing simplifies to:

public void method1()
{
    Ilist<string> testList = new IList<string>(){"1","2","3"};
    Parallel.ForEach(testList, ()=>
    {
        method2();
    });
}
public void method2()
{
    // some other (plain old synchronous) code here
}

Solution 2

void async methods are 'fire and forget', and there's no way to wait for them to complete. When method2 is called in your parallel loop, it returns immediately, so your loop is only ensuring the tasks in method2 are created before the loop completes.

You can change the return type of method2 to Task which will allow you to wait on the result of the operation e.g.

public async Task method()
{
     await Task.Run(() { some other code here });
}

which you can wait for in your loop with

method2().Wait();

although doing this is no better than just running the body of the task in method2 directly in your foreach delegate.

Share:
16,150
user1438980
Author by

user1438980

Updated on June 04, 2022

Comments

  • user1438980
    user1438980 almost 2 years

    I have an async method which will be used in Parallel.Foreach. in the async method there is await for a Task. However, in the test, seems there are no await behavior, the await Task didn't complete. What's the problem? Below is the code.

    public void method1()
    {
      Ilist<string> testList = new IList<string>(){"1","2","3"};
      Parallel.ForEach(testList, ()=>
      {
           method2();
      });
    }
    public async void method2()
    {
       await Task.run(()=>{  some other codes here });  
    }
    
  • user1438980
    user1438980 about 11 years
    Yes, you are right, it works. The reason I have to run in method2 because I have to pass different Func to the method1. like create, delete, etc. thanks a lot .