Задача. Когда не все задачи были выполнены; возвращается по завершении первого задания - PullRequest
0 голосов
/ 09 июля 2019

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 Ответ

1 голос
/ 09 июля 2019

Вы не правильно различаете WaitAll и WhenAll.WhenAll само по себе ожидаемо, а WaitAll - нет.Вы либо хотите это:

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

или это:

Await Task.WhenAll(taskList)

'All tasks completed.

Вы должны прочитать документацию для этих методов.Вы должны ВСЕГДА читать соответствующую документацию, когда что-то не работает, как вы ожидаете.Сайты, подобные этому, являются последним средством, а не первым вариантом.

РЕДАКТИРОВАТЬ:

Я только что понял, что вы ожидаете Task.WhenAll, но затем вы игнорируете этот результат и снова вызываете Task.WhenAll безв ожидании этогоСначала я увидел второй звонок и больше не смотрел, чтобы заметить первый звонок.Я приведу пример, который, надеюсь, прояснит ситуацию.

РЕДАКТИРОВАТЬ:

Вот пример того, как позвонить WhenAll.Для этого кода требуется форма Windows с Button и TextBox с 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.

...