我正在尝试等待.NET 4中的Task结果,就像在.NET 4.5中使用await关键字一样。我只是无法弄清楚如何做到这一点......
我的代码(以证明我至少要尝试):
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调用在不同的线程上执行,但该函数必须等待结果才能返回。不幸的是,这阻止了我的主线程,直到任务完成,我没有丝毫的线索如何使它等待而不阻塞。我不想使用Async CTP,因为那只是逃避问题。
秘诀是什么?
答案 0 :(得分:3)
没有秘密酱。如果你想创建一个返回某个异步操作结果的方法,你只需要阻塞该操作,直到操作完成。
但还有其他方法可以实现同样的目标。在.Net中执行此操作的“旧”方式与WebRequest
使用相同:有两种方法BeginGetXDocument
和EndGetXDocument
。然后,您可以将委托传递给将在操作完成时执行的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()
。