2

私は、2000以上の企業向けのダウンロードデータルーチンを起動するコードを持っています。この例を単純にするために、ダウンロードルーチンを300秒待つように変更しました。以下は、呼び出し元によって複数回呼び出される単一の会社のルーチンです。発信者からタスクの数を制限する

Public Async Function DoJob(ByVal company As Company) As Task(Of Boolean) 
    Console.WriteLine(String.Format("Started:{0}", company.CompanySymbol)) 
    For i As Long = 1 To 300 
     Await Task.Delay(1000).ConfigureAwait(False) 
    Next 
    Console.WriteLine(String.Format("Ended:{0}", company.CompanySymbol)) 
    Return True 
End Function 

、私が使用します。

Dim downloadTasksQuery As IEnumerable(Of Task(Of Boolean)) = 
       From company In companies Select DoJob(company) 
'***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) 

これはありませんが、それがインターネットに取得し、戻って応答を有するまで、すべてのタスクとタスクがキューに入れられる並列火災です。タスクの数が多いため、多くのタスクが時間切れになっている。なぜなら、いつでもそのような応答を待っているタスクの数が膨大なので、時間内に応答を返すことができないからである。 (上記のDoJobメソッドでは300秒待つだけの長時間実行されるタスクに置き換えて、物事を単純にしておくために実際のダウンロードコードを削除したことを覚えておいてください)。

私がやりたいことは、解雇できるタスクの数を制限することです。つまり、50のタスクだけがアクティブになり、残りのタスクが50の束から完了するのを待ってから、タスクが完了すると、キューに入れられます。

私はこれ試してみました:

Dim options As New ParallelOptions() 
options.MaxDegreeOfParallelism = 100 
Parallel.ForEach(companies, options, Sub(company) 
               ' logic 
               DoJob(company) 
              End Sub) 

をしかしDoJobからのプリントは、すべての2000+の項目に来て、(代わりに100最初の、一度にすべてのタスクを発射して、待っている。このように見えますタスクは完了します)。

ここにも

同じ問題:

Dim listOfActions = New List(Of Action)() 
For Each company In companies 
    ' Note that we create the Action here, but do not start it. 
    listOfActions.Add(Function() DoJob(company)) 
Next 

Dim options As New ParallelOptions() 
options.MaxDegreeOfParallelism = 100 
Parallel.Invoke(options, listOfActions.ToArray()) 

私は、それはまた同じ振る舞いを見せているHow to limit the Maximum number of parallel tasks in c#

に@ClearLogicsの例を試してみました。すべてのタスクはすぐに解雇されます。

これを回避するにはどうすればいいですか?100個のタスクを起動し、その後キューイングを続けるだけで、100個以上のタスクがありません。

+0

[並列タスクライブラリを介して実行されているアクティブなタスクの数を制限する最善の方法](https://stackoverflow.com/questions/11138927/best-way-to-limit-the-number-of-アクティブタスク - 実行中 - 並列タスク - ライブラリ) – cassandrad

答えて

0

MaxDegreeOfParallelismについてのご意見は間違っています。thisの記事をご覧ください。なぜ2000スレッドが同時に開始されたのかを説明しています。 Await Task.Delay(1000).ConfigureAwait(False)が実行されると、スレッドは空いているとみなされ、次のタスクで開始することができます。

私がやりたいことは、解雇できるタスクの数を制限することです。

自分で実装する必要があります。

  1. のようにカスタムTaskSchedullerを実装してください。
  2. 上位レベルで作成されたタスクの量を制御します。たとえば、セマフォを使用して並行タスクを制御します。例はhereです。

2番目のオプションを選択する場合は、セマフォでの作業のイラストだけであることを警告します。つまりコードは生産用ではありません。

関連する問題