Parallel.ForEach and async-await

48,307

Ahh, okay. I think I know what's going on now. async method => an "async void" which is "fire and forget" (not recommended for anything other than event handlers). This means the caller cannot know when it is completed... So, GetResult returns while the operation is still running. Although the technical details of my first answer are incorrect, the result is the same here: that GetResult is returning while the operations started by ForEach are still running. The only thing you could really do is not await on Process (so that the lambda is no longer async) and wait for Process to complete each iteration. But, that will use at least one thread pool thread to do that and thus stress the pool slightly--likely making use of ForEach pointless. I would simply not use Parallel.ForEach...

Share:
48,307
sreginogemoh
Author by

sreginogemoh

Updated on October 30, 2021

Comments

  • sreginogemoh
    sreginogemoh over 2 years

    I had such method:

    public async Task<MyResult> GetResult()
    {
        MyResult result = new MyResult();
    
        foreach(var method in Methods)
        {
            string json = await Process(method);
    
            result.Prop1 = PopulateProp1(json);
            result.Prop2 = PopulateProp2(json);
    
        }
    
        return result;
    }
    

    Then I decided to use Parallel.ForEach:

    public async Task<MyResult> GetResult()
    {
        MyResult result = new MyResult();
    
        Parallel.ForEach(Methods, async method =>
        {
            string json = await Process(method);    
    
            result.Prop1 = PopulateProp1(json);
            result.Prop2 = PopulateProp2(json);
        });
    
        return result;
    }
    

    But now I've got an error:

    An asynchronous module or handler completed while an asynchronous operation was still pending.