我有一个从电子邮件标题中提取值的函数。为了加快速度,想要使用框架4.5中的async。这是我第一次尝试使用异步。
我连续几次异步调用提取函数来提取不同的值。来自电子邮件标题。我遇到的问题是如何知道所有实例何时完成。我找到了一些例子,但没有一个符合条件任务的情况。
我相信我需要:
但是,我不知道该怎么做。
'Extract these vars from header if no value was passed
'Calling HeaderExtract Async for speed
If Len(sClient) = 0 Then
sClient = HeaderExtractAsync("Client,", sHeaders).Result
' --> Add this as a new task?
End If
If Len(sSubscriptionNum) = 0 Then
sSubscriptionNum = HeaderExtractAsync("SubscriptionNum,", sHeaders).Result
End If
If Len(sTargetID) = 0 Then
sTargetID = HeaderExtractAsync("TargetID,", sHeaders).Result
End If
If Len(sAddressBook) = 0 Then
sAddressBook = HeaderExtractAsync("AddressBook,", strHeaders).Result
End If
' --> Check that all are done?
答案 0 :(得分:1)
好。您似乎正在使用异步编程,但您根本就没有使用它,首先我建议您在此处阅读:http://blogs.msdn.com/b/windowsappdev/archive/2012/04/24/diving-deep-with-winrt-and-await.aspx和此处:http://blogs.msdn.com/b/windowsappdev/archive/2012/06/14/exposing-net-tasks-as-winrt-asynchronous-operations.aspx,这些资源适用于WinRT,但您可以得到照片。
现在,你的方法返回一个Task<TResult>
(这很好),但是通过调用Result
你实际上是在同步,因为Result总是在返回之前等待Task结束。使这种异步的方式如下:
If Len(sClient) = 0 Then
Dim tClient as Task(Of Whatever) = HeaderExtractAsync("Client,", sHeaders)
tClient.Start()
End If
然后检查任务是否已完成,如下:
If tClient.IsCompleted Then
DoSomething()
Else
ContinueWaiting();
End If
可能你可能想把它放在一个循环中,这样你就可以确定如果任务没有完成,你就等到它完成。
修改强>
我意识到你似乎想要将任务用作线程,即使你可以这样做,任务也不是完美的,任务对于触发可能需要一段时间才能完成的活动意味着更多,然后当它完成它会将控件返回到调用函数的确切位置,而不会阻塞主线程(通常是UI线程),记住这一点你也可以在这里阅读:http://blogs.msdn.com/b/benwilli/archive/2013/04/24/tasks-are-not-threads.aspx,这里是一个关于如何正确使用任务的示例,假设HeaderExtractAsync
需要一段时间才能完成:
If Len(sClient) = 0 Then
sClient = Await HeaderExtractAsync("Client,", sHeaders)
End If
答案 1 :(得分:1)
首先,运行HeaderExtract
需要多长时间,启动异步任务会产生非常大的开销,如果HeaderExtract
快速返回,您的程序可能会变慢
2,您没有获得等待的任何好处,您需要致电Await Foo()
以使其对消息泵进行控制,Foo().Result
将阻止您的程序并使您的UI无响应(如果这是在ui线程上)
最后,如果确实需要一段时间才能完成,您需要启动所有任务 然后 检查结果,否则您将等待第一个结果在你开始寻找第二个结果之前回来。
'Extract these vars from header if no value was passed
'start off all the tasks before we start checking for results
If Len(sClient) = 0 Then
tClient = HeaderExtractAsync("Client,", sHeaders)
End If
If Len(sSubscriptionNum) = 0 Then
tSubscriptionNum = HeaderExtractAsync("SubscriptionNum,", sHeaders)
End If
If Len(sTargetID) = 0 Then
tTargetID = HeaderExtractAsync("TargetID,", sHeaders)
End If
If Len(sAddressBook) = 0 Then
tAddressBook = HeaderExtractAsync("AddressBook,", strHeaders)
End If
'now start waiting for results
If tClient IsNot Nothing
sClient = Await tClient
If tSubscriptionNum IsNot Nothing
sSubscriptionNum = Await tSubscriptionNum
If tTargetID IsNot Nothing
sTargetID = Await tTargetID
If tAddressBook IsNot Nothing
sClsAddressBookient = Await tAddressBook
如果你想让线程休眠而不是等待(比如你没有使用.NET 4.5而你刚刚在你的OP中使用了错误的标签)用sFoo = await tFoo
<替换sFoo = tFoo.Result
行/ p>