0

複数のURLをダウンロードするためのタスクを起動します。並行タスクを実行するためのリストの分割

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) 

companiesリストには2000種類のURLが含まれています。私は、リストの終わりに向かって追加されたURLがより頻繁にタイムアウトすることを観察しています。私は再試行論理を整えておき、次の試行でURLをダウンロードするこのタイムアウト状況を処理しています。しかし、リストの先頭に表示されているだけなので、URLに優遇措置を取る必要はありません。

URLリストをチャンクする4つのメインタスクをそれぞれ500個(おそらくもっと管理しやすい)にして、上記のコードを使用できるかどうかを考えようとしていました。しかし、上記のコードであまり書き換えなくても、それを紹介する方法を見つけることはできません。どんな助けでも大歓迎です。

EDIT:もっとこのような

何か:

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 

これは、最小限のコード変更であるが、問題は、私はParallel.ForEachAwaitを使用することができないということです。

これを変更するには、どんな提案もあります。

+0

さらに、Parallel.ForEachをパーティションで使用するようなものです。更新された質問を投稿する。 – Kallol

答えて

1

VB.NETの人ではありませんが、私はimplementing a simple ForEachAsyncのStephen Toubの良い投稿が役に立ちます。

彼のポストから抜粋したコードでは、並列で実行できるオペランドの数を制限することができます。あなたの具体的な質問については

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); 
     })); 
} 

、あなたはそのようなとしてこれを使用することができます。

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

はそれがお役に立てば幸いです。