Task.WhenAll未完成所有任务;它在第一个任务完成时返回

时间:2019-07-09 05:41:39

标签: vb.net async-await task-parallel-library

Task.WhenAll在第一个任务完成时返回。我只是循环记录并将其添加到taskList,然后等待Task.WhenAll,但是在调试时,我发现它在完成第一个任务后返回到主函数。请检查我的TrackPackages函数:

Public Async Function TrackPackages(ByVal trackingNos As String) As Task(Of String)

    Dim trackResponseXml As String = String.Empty
    Dim skipNos As Integer = 0
    Dim takeNos As Integer = 10
    Dim strResponses As String = String.Empty
    Dim taskList As List(Of Task(Of String)) = New List(Of Task(Of String))()

    If Not String.IsNullOrEmpty(trackingNos) Then
        Dim totalTrackingNos As List(Of String) = trackingNos.Split(","c).ToList()
        skipNos = 0
        'Dim totallparalleltask = (totalTrackingNos.Count / 35)
        'For var = 0 To totallparalleltask
        While skipNos < totalTrackingNos.Count
            Dim trackingNoArray = totalTrackingNos.Skip(skipNos).Take(takeNos).ToList()
            taskList.Add(Task.Run(Function() GetTrackResponseXML(trackingNoArray)))

            skipNos = skipNos + 10
        End While
        'Next var
        Dim lastindex As Integer = 0

        'Here is issue with task.whenall it returns on completion of first task
        Dim alltaskstring = Await Task.WhenAll(taskList.ToArray)

        If (Task.WhenAll(taskList).IsCompleted) Then
            'Dim abcsdsd As String = Await GetTrackResponseString(item, trackResponseXml)
            Return trackResponseXml
        End If
    End If

End Function

它应该完成Task.WhenAll(taskList)中的所有任务。

1 个答案:

答案 0 :(得分:1)

您没有正确地区分WaitAllWhenAllWhenAll本身是可以等待的,而WaitAll不是。您要么想要这个:

If Task.WaitAll(taskList) Then
    'All tasks completed.

或者这个:

Await Task.WhenAll(taskList)

'All tasks completed.

您应该阅读这些方法的文档。当某些功能无法正常工作时,您应该始终阅读相关文档。这样的网站是不得已而为之,不是第一选择。

编辑:

我刚刚意识到您正在等待Task.WhenAll,但是您忽略了该结果并再次调用Task.WhenAll,而没有等待它。我首先看到了第二个电话,再也没有注意到第一个电话。我将提供一个示例,希望可以将其清除。

编辑:

这是如何调用WhenAll的示例。此代码需要Windows窗体,其中包含ButtonTextBoxMultiline设置为True。该代码启动了10个返回String的任务,并通过调用WhenAll并等待它们来等待它们完成。完成所有任务后,WhenAll返回一个包含每个任务结果的数组。

Private rng As New Random

Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim tasks As New List(Of Task(Of String))

    For i = 1 To 10
        tasks.Add(GetTimeStringAsync(i))
    Next

    'Wait for all tasks to complete and aggregate the results.
    Dim results = Await Task.WhenAll(tasks)

    'Use the aggregated results.
    TextBox1.Lines = results
End Sub

Private Async Function GetTimeStringAsync(number As Integer) As Task(Of String)
    'Get the current time as text after a random delay of between 2 and 10 seconds.
    Return Await Task.Run(Async Function()
                              Await Task.Delay(rng.Next(2000, 10000))

                              Return $"{number}: {Date.Now:HH:mm:ss.fffff}"
                          End Function)
End Function

请注意,如果任务方法的类型为Task(Of T),则返回类型WhenAllTask(Of T())。对于您和我来说,这意味着等待WhenAll会产生一个String数组。