0

A couple years ago I was a little stuck on implementing async/await for the first time. I got an answer to my question [on this site], and I went on my merry way.

But lately, I got called out saying "that's not running those calls in parallel", even though it was VERY close to the exact solution that I received earlier.

Now I'm having second thoughts.

Here's the background, and the possible resolutions.

The whole point is that I don't want to execute method 1, wait for the results, then execute method 2 and wait for those results. That's too slow when the two method calls have nothing to do with each other.

I want to perform two method calls, both of which happen to be going to a database, but it could be anything, and I don't want processing to continue until I have the result of both calls.

public async Task<DataViewModel> GetDataInParallel()
{
    var asyncStuff = new
    {
        result1 = await _databaseRepo.QuerySomething(),
        result2 = await _databaseRepo.QuerySomethingElse()
    };

    return new DataViewModel(asyncStuff.result1, asyncStuff.result2);
}

vs

public async Task<DataViewModel> GetDataInParallel()
{
    var result1Task = _databaseRepo.QuerySomething();
    var result2Task = _databaseRepo.QuerySomethingElse();

    var asyncStuff = new
    {
        result1 = await result1Task,
        result2 = await result2Task
    };

    return new DataViewModel(asyncStuff.result1, asyncStuff.result2);
}

I use both versions in my website, but now I'm wondering if the ones that use option 1 are not doing things in parallel, and I'm seeing a performance degradation.

I'm not exactly sure on how to prove this out; does anyone know which is the correct version that will execute the two method calls in parallel? Or are they both right/wrong?

5
  • You're right... option1 does not do anything in "parallel." When you await something, the code below will not execute until the awaitable has completed. The second option is good. Commented Aug 21, 2018 at 17:18
  • @JohnWu I"m not worried about the code below the await's. I only want the 2 function calls to execute (or start executing) at the same time. Commented Aug 21, 2018 at 17:20
  • With all due respect, I think you are worried about code below an await-- in your first example, the second database call is below an await, so it will not be started until the first one has finished. I think you want it to start before the first one is finished, as it will in your second example, where it is not below an await. Commented Aug 21, 2018 at 17:21
  • @JohnWu thanks. So are you saying that option 2 DOES kick off both at the same time; since both method calls appear before any awaits? Commented Aug 21, 2018 at 17:22
  • @JohnWu can you post your comments as an answer as well so I can upvote you too? Commented Aug 21, 2018 at 17:26

1 Answer 1

2

First version waits for first operation before starting second, so it is not parallel.

Second version does run them in parallel (starts both, then awaits both). You can make it more obvious by using Task.WhenAll:

public async Task<DataViewModel> GetDataInParallel()
{
    var result1Task = _databaseRepo.QuerySomething();
    var result2Task = _databaseRepo.QuerySomethingElse();

    await Task.WhenAll(result1Task, result2Task);

    return new DataViewModel(result1Task.Result, result2Task.Result);
}

See why WhenAll is a better choice: Why should I prefer single 'await Task.WhenAll' over multiple awaits?

Sign up to request clarification or add additional context in comments.

2 Comments

Wow, so neither run in parallel!?!?! Should give my site a big performance boost when I fix all of them. Appreciate the quick answer!
I've fixed my answer. I was wrong about second one, it is actually parallel!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.