私は、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個以上のタスクがありません。
[並列タスクライブラリを介して実行されているアクティブなタスクの数を制限する最善の方法](https://stackoverflow.com/questions/11138927/best-way-to-limit-the-number-of-アクティブタスク - 実行中 - 並列タスク - ライブラリ) – cassandrad