2014-04-20 124 views
6

我試圖很好地理解異步/等待,並且想清除一些混淆。可有人請解釋什麼將是下面的執行方面的區別:異步/等待執行差異

// version 1 
public Task Copy(string source, string destination) { 
    return Task.Run(() => File.Copy(source, destination)); 
} 

public async Task Test() { 
    await Copy("test", "test2");  
    // do other stuff 
} 

和:

// version 2 
public async Task Copy(string source, string destination) { 
    await Task.Run(() => File.Copy(source, destination)); 
} 

public async Task Test() { 
    await Copy("test", "test2"); 
    // ... 
} 

他們是否導致相同的代碼,爲什麼我會寫一個比其他?

+1

可能是一個重複:http://stackoverflow.com/q/21033150/1768303 – Noseratio

+1

@Noseratio是的,這的確是,也Erics答案是一個「大開眼界」,抱歉的dup,沒有找到任何東西(不確定如何制定搜索:P) –

+2

@DimitarDimitrov,IMO,除了狀態機的開銷之外,最主要的區別是[異常傳播邏輯](http://stackoverflow.com/a/21082631/1768303) 。 – Noseratio

回答

8

首先讓我先說兩點代碼都是而不是一樣。

您的版本1代碼將僅創建一個「狀態機」,因爲它僅包含等待Test方法。

您的版本2代碼將爲CopyTest方法創建兩個「狀態機」,這會增加一些開銷。

爲什麼我們使用async方法?簡單就是讓我們的代碼在處理「異步任務」時可讀,優雅。它使我們的代碼更優秀,避免回調和延續等

讓我們打破什麼Copy方法做,我們回答這個問題 我們是否真的需要它是async

Copy方法只是委託調用Task.Run返回,最終達到對File.Copy的完成完成的任務。所以意圖很明確,我們需要一個通知File.Copy完成的任務。這種方法可以滿足您的所有需求,無需按照預期方式運行即可使用async

那麼,你什麼時候需要async

當您需要在早期任務完成時繼續執行某些代碼時,您需要異步(繼續)。

例子:

public async Task Test() 
{ 
    await Copy("test", "test2"); 
    DoPostCopied(whatever); 
    await DoPostCopied2();//Etc 
} 

你可以僅僅通過反編譯兩個版本驗證async和非異步方法之間的差異。它太長,不會被讀取,所以我跳過了這裏。

結論:僅在需要時使用async。在這種情況下,版本1更好,您應該比版本2更喜歡它。

+0

+1指出他們是不一樣的 –

+1

@AmitJoki我想我們需要爲op提供+1以及完成有趣的問題 –

+0

。確實這是一個很好的問題 –