1

ファイルからデータを読み取り、解析/変換してからデータベースに挿入するために、BlockingCollection に裏打ちされたプロデューサー/コンシューマー パターンを使用しています。私が持っているコードは、ここにあるものと非常によく似ています: http://dhruba.name/2012/10/09/concurrent-producer-consumer-pattern-using-csharp-4-0-blockingcollection-tasks/

ただし、主な違いは、コンシューマ スレッドがデータを解析するだけでなく、データベースに挿入することです。このビットは遅く、スレッドがブロックされていると思います。

この例では、2 つのコンシューマ スレッドがあります。ある程度インテリジェントな方法でスレッドの数を増やす方法があるかどうか疑問に思っていますか? スレッドプールがこれを行うと思っていましたが、それがどのように行われるかを把握できないようです。

あるいは、コンシューマ スレッドの数をどのように選択しますか? 2 は私には正しくないようですが、最良の # が何であるかはわかりません。消費者スレッドの数を選択する最良の方法について考えていますか?

4

1 に答える 1

3

コンシューマ スレッドの数を選択する最善の方法は、数学です。プロデューサから 1 分あたりに受信するパケットの数を計算し、それを 1 つのコンシューマが処理できる 1 分あたりのパケット数で割ります。あなたが必要とする多くの消費者。

ブロッキング出力の問題 (データベースを更新しようとするときにコンシューマーがブロックする)BlockingCollectionを、コンシューマーが完了したパケットを入れる別のスレッドを追加することで解決しました。別のスレッドがそのキューを読み取り、データベースを更新します。したがって、次のようになります。

input thread(s) => input queue => consumer(s) => output queue => output thread

これには、消費者を出力から切り離すという追加の利点があります。つまり、消費者に影響を与えることなく、出力を最適化したり、出力方法を完全に変更したりできます。これにより、たとえば、データベースの更新をバッチ処理して、レコードごとに 1 つのデータベース呼び出しを行うのではなく、1 回の呼び出しで 12 または 100 (またはそれ以上) のレコードを更新できるようになります。

この非常に単純な例 (1 つのコンシューマーを使用) は、私の記事Simple Multithreading, Part 2で示しています。これはテキスト ファイル フィルターで機能しますが、概念は同じです。

于 2013-07-31T20:29:28.953 に答える