最好的.net 4.5异步方法来了解多个条件任务何时完成?

时间:2013-06-14 06:31:16

标签: .net vb.net asynchronous async-await asp.net-4.5

我有一个从电子邮件标题中提取值的函数。为了加快速度,想要使用框架4.5中的async。这是我第一次尝试使用异步。

我连续几次异步调用提取函数来提取不同的值。来自电子邮件标题。我遇到的问题是如何知道所有实例何时完成。我找到了一些例子,但没有一个符合条件任务的情况。

我相信我需要:

  • 调暗任务数组
  • 将所有必要的任务添加到数组
  • 然后,使用Task.WhenAll

但是,我不知道该怎么做。

            '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?

2 个答案:

答案 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>