7

次のワークフローでプロジェクトに取り組んでいます。

パート 1:

  • イベントは非同期に到着し、ブロッキング キューに入れられます。これをQ1と呼びます
  • スレッドは、そのキューから次に利用可能なアイテムを取得します
  • アイテムは {N} 個のタスクを並行して実行することになります
  • 各タスクはその結果を 2 番目のキューに入れます。これをQ2と呼びます。
  • アイテムの処理が終了すると、次のアイテムがキューから読み取られます。

パート2:

  • 別のスレッドがQ2から一度に 1 つのオブジェクトを読み取り、結果を処理します。

したがって、ここでの問題は、最初のキューのすべてのアイテムが多数のタスクを並行して実行することになり、各タスクがその結果をキューに入れることです。2 番目のキューは、一度に 1 アイテムずつ順次処理する必要があり、フラッディングされています。


私の質問

Q2の項目数が特定のしきい値を下回るまで、 Q1を処理するスレッドを待機させるメカニズムが必要です。これを達成するための最良の方法は何ですか?ポーリング ソリューションではなくイベント ドリブン ソリューションを使用する方法はありますか?

4

3 に答える 3

9

を使用する代わりに、Q2 にQueue<T>を使用できます。BlockingCollection<T>を設定すると、容量に達するBoundedCapacityと への呼び出しがブロックされます。Q2.Add()これにより、Q1 の処理が自動的に調整されます。これは、N 個のタスクが最終キューに追加できない場合にブロックが開始されるためです。

于 2013-03-06T17:04:12.073 に答える
2

第 2 四半期に追いつくことができる長い干ばつを伴う時折の洪水でデータを受け取ることを想定しています。Q1 から生成された同時実行スレッドの数を、これらのタスクに限定されたスレッド プールを使用して単純に制限することを検討しましたか?

ジョブのサイズが到着時に簡単に判断できる場合は、複数のスレッド プールを利用できると思います。大きなジョブを処理するために少数のスレッドを用意し、小さなジョブを処理するために多数のスレッドを用意することができます。3 番目の中間キューでさえ有益な場合があります。

于 2013-03-06T17:05:07.043 に答える
1

TPL Dataflowあなたの問題は、ライブラリによって解決される完璧な例のようです。試してみたい場合は、次のように機能します (もちろん、これは非常に単純な例です)。

TransformBlock<int, bool> transform = new TransformBlock<int, bool>(i => i > 5 ? true : false,
            new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 4 });
ActionBlock<bool> resultBlock = new ActionBlock<bool>(b => Console.WriteLine("My result is : " + b),
            new ExecutionDataflowBlockOptions { BoundedCapacity = 10 });
transform.LinkTo(resultBlock);

変換を行う変換ブロックを定義しています (これは として機能しますQ1)。その並列処理レベルを、使用するタスクの数に設定できます。

次に、2 番目のブロック ( として機能) を作成します。このブロックQ2BoundedCapacity設定され、すべてのメッセージを同期的に処理し、各要素のアクションを呼び出します。BufferBlockこのブロックは、オンデマンドでポーリングできるようにするなど、他のブロックに置き換えることができます。

于 2013-03-06T17:09:29.223 に答える