【问题标题】:Task.WhenAll didn't complete all tasks; it returns on completion of first taskTask.WhenAll 没有完成所有任务;它在完成第一个任务时返回
【发布时间】:2019-07-09 16:23:43
【问题描述】:

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)的所有任务。

【问题讨论】:

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


    【解决方案1】:

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

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

    或者这个:

    Await Task.WhenAll(taskList)
    
    'All tasks completed.
    

    您应该阅读这些方法的文档。当某些事情无法按预期工作时,您应该始终阅读相关文档。像这样的网站是最后的手段,而不是第一选择。

    编辑:

    我刚刚意识到您正在等待Task.WhenAll,但随后您忽略了该结果并再次调用Task.WhenAll 而不等待它。我首先看到了第二个电话,并没有进一步注意到第一个电话。我将提供一个示例,希望可以解决问题。

    编辑:

    以下是如何调用WhenAll 的示例。此代码需要一个带有ButtonTextBox 的Windows 窗体,其中Multiline 设置为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),则WhenAll 的返回类型为Task(Of T())。在你和我的情况下,这意味着等待 WhenAll 会产生一个 String 数组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-20
      • 1970-01-01
      相关资源
      最近更新 更多