2012-11-14 55 views
10

什麼是.NET 4.0中await關鍵字的最佳選擇?我有一個方法需要在異步操作後返回一個值。我注意到wait()方法完全阻塞了線程,從而導致異步操作無用。在仍然釋放UI線程的同時運行異步操作的選項有哪些?在.NET 4.0中等待替代?

+1

使用await,但以正確的方式,我猜。你有一些代碼? – lboshuizen

+3

將VS2012與C#5.0一起使用,而將.NET 4.0作爲目標是否可以接受?請參閱[在.net 4上使用async-await](http://stackoverflow.com/questions/9110472/using-async-await-on-net-4) – CodesInChaos

+0

@CodesInChaos對於同事,不:)。 – Dante

回答

4

我覺得你的基本選項

最簡單的方法可能是安裝異步CTP。據我所知,許可證允許商業用途。它修補了編譯器,並帶有一個150KB的dll,你可以將它包含到你的項目中。可以使用Task.ContinueWith()。但這意味着,你必須採取一些措施來處理和控制流量。

任務是一個功能結構。這就是爲什麼ContinueWith()不能與命令性結構如for環或try-catch塊混合良好。因此asyncawait得到了介紹,以便編譯器可以幫助我們。

如果你不能得到編譯器的支持(即使用.Net 4.0),最好的方法是將TAP與功能框架一起使用。 Reactive Extensions是一個處理異步方法的非常好的框架。

剛剛谷歌的「反應擴展任務」開始。

1

你可以用yield協程來實現類似await的行爲,我在非4.5代碼中使用了這個。你需要的是從哪個應該運行異步方法檢索的YieldInstruction類:

public abstract class YieldInstruction 
{ 
    public abstract Boolean IsFinished(); 
} 

然後,你需要的YieldInstruction(AE TaskCoroutine它處理任務)的一些實現,並使用這種方式(僞代碼):

public IEnumerator<YieldInstruction> DoAsync() 
{ 
    HttpClient client = ....; 
    String result; 
    yield return new TaskCoroutine(() => { result = client.DownloadAsync(); }); 
    // Process result here 
} 

現在您需要一個調度程序來處理指令的執行。

for (Coroutine item in coroutines) 
{ 
    if (item.CurrentInstruction.IsFinished()) 
    { 
     // Move to the next instruction and check if coroutine has been finished 
     if (item.MoveNext()) Remove(item); 
    } 
} 

在開發WPF或WinForms的應用程序,你也能避免任何Invoke呼叫如果您在合適的時間更新協程。你也許能夠延伸這個想法,讓你的生活更加輕鬆。示例:

public IEnumerator<YieldInstruction> DoAsync() 
{ 
    HttpClient client = ....; 
    client.DownloadAsync(..); 

    String result; 
    while (client.IsDownloading) 
    { 
     // Update the progress bar 
     progressBar.Value = client.Progress; 
     // Wait one update 
     yield return YieldInstruction.WaitOneUpdate; 
    } 
    // Process result here 
}