Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When do multiple awaits make sense?

I have some misunderstanding with c# async/await mechanism. Is there any essential difference between

private async void Init()
{
    await Task.Run(() => Do1());
    await Task.Run(() => Do2());
}

and

private async void Init()
{
    await Task.Run(() => 
    {
       Do1();
       Do2();
    });
}

The only difference I see: in the first sample Do1 and Do2 will be run in different threads while in the second sample - in the same thread. But again, what is the real benefit of it and when I should prefer the 1st approach over the second one and vice versa?


EDIT: The second case

What is the difference between

private async void Init()
{
    await Task.Run(() => Do1());
    Do3();
}

and

private async void Init()
{
    await Task.Run(() => 
    {
       Do1();
       Do3();
    });
}
like image 762
Sergey Avatar asked Jul 08 '26 13:07

Sergey


1 Answers

The difference is:

First example:

  • You queue Do1 on a threadpool thread and asynchronously wait for it to complete, then do the exact same with Do2. These may run on different threads.
  • You queue Do1 and Do2 to execute synchronously one after the other on the same thread pool thread.

Second example:

  • Queue Do1 on the threadpool and asynchronously wait for it to complete, then invoke Do3 synchronously.
  • This is exactly the same as the second part of the first example.

Note that when you await, you asynchronously wait for the operation to complete, hence unless the method finishes it won't execute the next line of code.

I'm assuming you're asking yourself if one is preferable to the other, and as in most cases, it depends. If you're running inside a console app, and you're going to asynchronously wait for Do1 to complete anyway, then pass both methods to the same Task.Run invocation. If you're planning on doing this in a place where synchronization matters, such as a GUI application, then any operation which needs to interact with UI controls should be invoked on the UI thread.

Another option which is more common is when you have two operations which are independent of each other and you want to start them together and wait for both to complete. This is where you'd use Task.WhenAll:

var firstDo = Task.Run(() => Do1());
var secondDo = Task.Run(() => Do2());
await Task.WhenAll(firstDo, secondDo);

Side note:

Do not use async void in asynchronous methods with no return value, that is what async Task is for. The former is only meant to allow compatibility with event handlers, where I'm assuming this isn't the case.

like image 62
Yuval Itzchakov Avatar answered Jul 11 '26 03:07

Yuval Itzchakov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!