2012-04-30 35 views
0

我想在.NET 4中等待任務結果,就像在.NET 4.5中使用await關鍵字一樣。我只是無法弄清楚如何做到這一點,但....NET 4中的非阻塞Task.wait?

我的代碼(證明我ATLEAST想):

Private Function GetXDocumentFromWebLocationAsync(ByVal request As WebRequest) As XDocument 
     Dim queryTask As Task(Of WebResponse) 
     queryTask = task(Of WebResponse).Factory.FromAsync(AddressOf request.BeginGetResponse, AddressOf request.EndGetResponse, Nothing, Nothing) 
     Return XDocument.Load(queryTask.Result.GetResponseStream) 
    End Function 

正如你所期望的,GetResponse的調用執行上一個不同的線程,但函數必須等待結果才能返回。不幸的是,這阻止了我的主線程,直到任務完成,並且我沒有絲毫思考如何讓它等待而沒有阻塞。我不想使用異步CTP,因爲這只是遠離問題。

什麼是祕密醬?

+0

'異步CTP ...只是遠離問題。'我想說異步CTP「解決」了這個問題。對於他自己的,我猜... –

+0

排序,但CTP更像是.NET 4.5將帶來的預覽。不是你在生產代碼中使用的東西。而且,由於它建立在任務API上,所以應該可以做到沒有,對吧? –

+1

好吧,我已經在生產代碼中使用了它很長一段時間,但我也有一個非常有限的用戶羣。 :) CTP實際上更像是VS11編譯器的預覽版;如果需要,可以使用VS11 Beta和「.NET 4異步定位包」來開發.NET 4解決方案。它建立在任務上 - 有點 - 但要做一個確切的重複[是很多工作](http://msmvps.com/blogs/jon_skeet/archive/tags/Eduasync/default.aspx)。 –

回答

3

沒有祕密的醬油。如果你想創建一個方法返回一些異步操作的結果,你只需要阻塞該線程直到操作完成。

但還有其他方法可以實現同樣的目的。在.Net中這樣做的「舊」方式是相同的WebRequest用途:有兩種方法BeginGetXDocumentEndGetXDocument。然後,您可以將代理傳遞給Begin方法,該方法將在操作完成時執行。

這樣做的另一種方法是從您的方法返回一個Task。要做到這一點,你可以用ContinueWith()

Private Function GetXDocumentFromWebLocationAsync(ByVal request As WebRequest) As Task(Of XDocument) 
    Dim queryTask As Task(Of WebResponse) 
    queryTask = Task(Of WebResponse).Factory.FromAsync(
     AddressOf request.BeginGetResponse, AddressOf request.EndGetResponse, Nothing, Nothing) 
    Return queryTask.ContinueWith(
     Function(antecendent) XDocument.Load(antecendent.Result.GetResponseStream)) 
End Function 

這種方式,方法的消費者可以選擇等待同步(使用Wait()Result)的結果,也可以再次使用ContinueWith()

在GUI應用程序中使用ContinueWith()時,您必須小心:默認情況下,延期在ThreadPool線程上運行。要在GUI線程上運行延續,可以使用TaskScheduler.FromCurrentSynchronizationContext()。或者特定於您的GUI庫的方法(WPF中的Dispatcher.Invoke(),Winforms中的Control.Invoke())。

+0

因此,如果我理解正確,我可以在ContinueWith()調用中鏈接我的代碼的其餘部分以避免塊? –

+0

是的,確切地說。但不要忘記,這會將方法的返回類型從'X'更改爲'Task(Of X)'。但是如果你想在整個方法中等待幾件事情,那麼使用'ContinueWith()'可以使你的代碼不可讀取得很快。這就是C#5「等待」發光的地方。 – svick

+0

我仍然認爲它比開始/結束方法和事件處理程序都好! –