2016-07-25 44 views
3

的這是我實現異步電動機在Windows /等待窗體應用程序迷惑,對正確使用異步/等待

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}"; 
} 

播放5秒後,結果在TextBox是「3000 & 5000」。

但是,當我修改button1_Click這樣的:

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}"; 
} 

的結果是一樣的,但它需要8秒。

爲什麼button1_Click的第二版充當同步?

+1

在第二種情況下,在DoAsync1()完成之前,您不運行DoAsync2()。這不清楚嗎?在[msdn](https://msdn.microsoft.com/en-us/library/mt674882.aspx)上有一個很好的圖解釋了'async/await'背後發生了什麼,請研究一下。 – Sinatr

+0

當引用一個'Task'時,它開始執行! 「await」說,當你完成時,在這裏重新輸入我的方法。 –

+0

http://stackoverflow.com/文檔/c%23/48/async-await#t=201607251201374786908 – Neel

回答

5

下面是差異的解釋:

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}"; 

雖然:

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}"; 

所以在第一個版本,這兩個任務同時運行。而在第二個版本中,您從不運行第二個任務,直到第一個任務完成。

我認爲閱讀Article會對您的知識有很大的幫助。

4

有了一些意見,使實際發生的事情更清楚:

// 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; 

對於第二種情況:

// 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(); 
2

DoAsync1DoAsync2回報awaitable Task -objects。如果你一個一個地等待它們,那麼它們會一個接一個地執行(首先等待第一個完成,然後等待第二個完成)。爲了平行運行它們,您可以先簡單地創建Task對象,然後等待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}"; 
}