0

Ich befehle Tasks zum Herunterladen mehrerer URLs.Partitionieren von Listen zum Ausführen paralleler Tasks

Dim downloadTasksQuery As IEnumerable(Of Task(Of Boolean)) = 
     From company In companies Select DownloadCompanyFromYahooAsync(company, numberOfDays) 
    ' ***Use ToList to execute the query and start the download tasks. 
    Dim downloadTasks As IEnumerable(Of Task(Of Boolean)) = downloadTasksQuery.ToList() 

    Await Task.WhenAll(downloadTasks) 

Die companies Liste enthält eine Art von 2000 URLs. Ich beobachte, dass URLs, die am Ende der Liste hinzugefügt werden, häufiger Zeitüberschreitung verursachen. Ich habe Logiken erneut versucht und bearbeite diese Timeout-Situation, die die URL beim nächsten Versuch herunterlädt. Ich möchte jedoch keine URL bevorzugt behandeln, nur weil sie am Anfang der Liste erscheint.

Daher wurde versucht zu denken, ob wir 4 Hauptaufgaben Gabelung der URL-Liste in jeweils 500 (wahrscheinlich besser handhabbar) und verwenden Sie den obigen Code. Ich bin jedoch nicht in der Lage, einen Weg zu finden, dies einzuführen, ohne im obigen Code zu viel schreiben zu müssen. Jede Hilfe wird sehr geschätzt.

EDIT:

Etwas mehr wie folgen aus:

Dim chunkPart As OrderablePartitioner(Of Tuple(Of Integer, Integer)) = Partitioner.Create(1, companies.Count, 500) 

    Parallel.ForEach(chunkPart, Sub(chunkRange) 
            For i As Integer = chunkRange.Item1 To chunkRange.Item2 - 1 
             Dim downloadTasksQuery As IEnumerable(Of Task(Of Boolean)) = 
             From company In companies.Skip(chunkRange.Item1).Take((chunkRange.Item2 - chunkRange.Item1) + 1) Select DownloadCompanyFromYahooAsync(company, numberOfDays) 
             Dim downloadTasks As IEnumerable(Of Task(Of Boolean)) = downloadTasksQuery.ToList() 
             Await Task.WhenAll(downloadTasks) 
            Next 
           End Sub 

Dies ist mit minimalen Änderungen am Code, aber das Problem ist, dass ich nicht Await in einem Parallel.ForEach verwenden kann.

Alle Vorschläge, um dies zu ändern.

+0

Etwas mehr wie Parallel.ForEach mit einer Partition verwenden. Eine aktualisierte Frage veröffentlichen. – Kallol

Antwort

1

Kein VB.NET-Typ, aber ich denke, Stephen Toub's guter Beitrag auf implementing a simple ForEachAsync könnte Ihnen hilfreich sein.

Einige Code-Schnipsel von seinem Beitrag erlauben es Ihnen, die Anzahl der Operationen zu begrenzen, die parallel ausgeführt werden können.

public static Task ForEachAsync<T>(this IEnumerable<T> source, int dop, Func<T, Task> body) 
{ 
    return Task.WhenAll( 
     from partition in Partitioner.Create(source).GetPartitions(dop) 
     select Task.Run(async delegate { 
      using (partition) 
       while (partition.MoveNext()) 
        await body(partition.Current); 
     })); 
} 

Für Ihre spezielle Frage haben, können Sie diese als solche verwendet werden:

public async Task DownloadForAllCompanies(List<string> companies, int numberOfDays) 
{ 
    await companies.ForEachAsync(4, async company => 
      { 
      await DownloadCompanyFromYahooAsync(company, numberOfDays); 
      }); 
} 

Hoffe, es hilft.

Verwandte Themen