Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different behavior async/await in almost the same methods

Tags:

Let's say I have two async methods

public async static Task RunAsync1() {     await Task.Delay(2000);     await Task.Delay(2000); } 

and

public async static Task RunAsync2() {     var t1 = Task.Delay(2000);     var t2 = Task.Delay(2000);      await t1;     await t2; } 

Then I use it like

public static void M() {     RunAsync1().GetAwaiter().GetResult();     RunAsync2().GetAwaiter().GetResult(); } 

In a result the RunAsync1 will run 4sec but RunAsync2 only 2sec
Can anybody explain why? Methods are almost the same. What is the difference?

like image 258
Roman Marusyk Avatar asked Jun 23 '17 09:06

Roman Marusyk


People also ask

Should you always await async methods?

If a method is declared async, make sure there is an await! If your code does not have an await in its body, the compiler will generate a warning but the state machine will be created nevertheless, adding unnecessary overhead for an operation that will actually never yield.

Which of the following is considered as the highly advantages feature of async await?

A significant benefit of the async/await pattern in languages that support it is that asynchronous, non-blocking code can be written, with minimal overhead, and looking almost like traditional synchronous, blocking code.

Which is the recommended way to wait for an async method to complete?

No problem, just make a loop and call this function with an await: [code] for (int i = pendingList. Count - 1; i >= 0; i--)

Does async await improve performance?

The main benefits of asynchronous programming using async / await include the following: Increase the performance and responsiveness of your application, particularly when you have long-running operations that do not require to block the execution.


2 Answers

In the second method 2 tasks are started at the same time. They will both finish in 2 seconds (as they are running in parallel). In the first method you first run one method (2 seconds), wait for it to complete, then start the second one (2 more seconds). The key point here is Task.Delay(..) starts right when you call it, not when you await it.

To clarify more, first method:

var t1 = Task.Delay(2000); // this task is running now await t1; // returns 2 seconds later var t2 = Task.Delay(2000); // this task is running now await t2; // returns 2 more seconds later 

Second method:

var t1 = Task.Delay(2000);  var t2 = Task.Delay(2000); // both are running now  await t1; // returns in about 2 seconds await t2; // returns almost immediately, because t2 is already running for 2 seconds 
like image 193
Evk Avatar answered Oct 13 '22 01:10

Evk


Just examine your code:

public async static Task RunAsync1() {     await Task.Delay(2000); // Start a delay task, and WAIT for it to finish     await Task.Delay(2000); // Start a delay task, and WAIT for it to finish } 

So the second await Task.Delay(2000); is called after the first call is finished (after 2 seconds).

While the second method,

public async static Task RunAsync2() {     var t1 = Task.Delay(2000); // Start a task     var t2 = Task.Delay(2000); // Start a task      await t1; // Wait for task to finish     await t2; // Wait for task to finish } 

So tasks t1, and t2 run at the same time.

If you change it to

public async static Task RunAsync3() {     var t1 = Task.Delay(2000); // Start a task     await t1; // Wait for task to finish      var t2 = Task.Delay(2000); // Start a task     await t2; // Wait for task to finish } 

you would get the same results as in RunAsync1.

like image 31
Pablo notPicasso Avatar answered Oct 13 '22 01:10

Pablo notPicasso