3

This is my implementation of async/await in Windows Forms Application

async Task<int> DoAysnc1() { await Task.Delay(3000); return 3000; } async Task<int> DoAsync2() { await Task.Delay(5000); return 5000; } private async void button1_Click(object sender, EventArgs e) { this.textBox1.Text = ""; var doAsync1 = DoAysnc1(); var doAsync2 = DoAysnc2(); var async1 = await doAsync1; var async2 = await doAsync2; this.textBox1.Text = $"{async1} & {async2}"; } 

After 5 seconds the result in the TextBox is "3000 & 5000".

But when I modify button1_Click like this:

private async void button1_Click(object sender, EventArgs e) { this.textBox1.Text = ""; var async1 = await DoAysnc1(); var async2 = await DoAysnc2(); this.textBox1.Text = $"{async1} & {async2}"; } 

the result is the same but it takes 8 sec.

Why second version of button1_Click act as synchronous?

4
  • 1
    In second case you don't run DoAsync2() until DoAsync1() is finished. Isn't that clear? There is a nice picture on msdn explaining what is happening behind async/await, study it please. Commented Jul 25, 2016 at 11:55
  • when take a reference to a Task, it starts executing! await says, when you're finished, re-enter my method here. Commented Jul 25, 2016 at 11:56
  • stackoverflow.com/documentation/c%23/48/… Commented Jul 25, 2016 at 12:02
  • @Nicorus: The second result is not acting synchronously; it's acting serially. Synchronous means "blocking the calling thread"; serial means "one at a time". Commented Jul 25, 2016 at 13:01

3 Answers 3

5

Below is the explanation of the difference:

this.textBox1.Text = ""; var doAsync1 = DoAysnc1(); // <--- Run DoAsync1 var doAsync2 = DoAysnc2(); // <--- Run DoAsync2 var async1 = await doAsync1; // <--- wait for DoAsync1 to finish var async2 = await doAsync2; //<--- wait for DoAsync2 to finish this.textBox1.Text = $"{async1} & {async2}"; 

While:

this.textBox1.Text = ""; var async1 = await DoAysnc1(); // <-- Run DoAsync1 and wait for it to be done var async2 = await DoAysnc2(); // <-- Run DoAsync2 and wait for it to be done this.textBox1.Text = $"{async1} & {async2}"; 

So in the first version, both tasks are running at the same time. While in the second version you never run the second task until the first is Completed.

I think reading this Article is going to be a big plus for your knowledge.

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

Comments

4

With some comments to make what actually happens more clear:

// Starts DoAsync1 asynchronously var doAsync1 = DoAysnc1(); // Starts DoAsync2 asynchronously var doAsync2 = DoAysnc2(); // From now on, both task are executing // Wait for DoAsync1 completion var async1 = await doAsync1; // Wait for DoAsync2 completion var async2 = await doAsync2; 

For the second case:

// Starts DoAsync1 asynchronously, and wait for the task completion (3s) var async1 = await DoAysnc1(); // Starts DoAsync2 asynchronously, and wait for the task completion (5s) var async2 = await DoAysnc2(); 

Comments

2

DoAsync1 and DoAsync2 return awaitable Task-objects. If you await them one by one then they are executed one after another (first wait for the first one to finish, then for the second one). In order to run them in parallel you can simply create the Task-objects first and wait for their results with Task.WhenAll.

private async void button1_Click(object sender, EventArgs e) { this.textBox1.Text = ""; var task1 = DoAysnc1(); var task2 = DoAysnc2(); await Task.WhenAll(task1, task2) this.textBox1.Text = $"{task1.Result} & {task2.Result}"; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.