2

System.Collections.Concurrent 名前空間を試していますが、設計の実装に問題があります。

  1. 入力キュー (ConcurrentQueue) は、起動時に I/O を実行して読み取りと解析を行っているスレッドから正常に読み込まれています。
  2. 次に、入力キューで Parallel.ForEach() を開始します。各項目で I/O バウンドの作業を行っています。
  3. ForEach() で処理されたアイテムごとにログ アイテムが作成され、結果キューにドロップされます。

私がやりたいことは、すべてのログ項目をメモリに収めることができない可能性があるため、入力の読み取りを開始するロギングを開始することです。アイテムが結果キューに到着するのを待つ最善の方法は何ですか? 見るべき設計パターンや例はありますか?

4

1 に答える 1

1

お探しのパターンはプロデューサー/コンシューマー パターンだと思います。より具体的には、TPL と BlockingCollection を中心に構築されたプロデューサー/コンシューマーの実装を持つことができます。

読みたい主な概念は次のとおりです。

  1. タスク
  2. ブロッキング コレクション,
  3. TaskFactory.ContinueWhenAll (一連のタスク/スレッドの実行が終了したときに何らかのアクションを実行できるようにします)。
  4. BlockingCollectionの境界とブロック。これにより、(メモリ上の理由から) 出力コレクションの最大サイズを設定できます。プロデューサー スレッドは、指定した最大サイズに達した場合にコンシューマーが要素を取得するのを待ちます。
  5. BlockingCollection.CompleteAddingおよびBlockingCollection.IsCompletedは、プロデューサーとコンシューマーを同期するために使用できます (プロデューサーはいつ終了したかを伝えることができ、コンシューマーはそれを確認し、プロデューサーが終了するまで実行を続けることができます)。

より完全なサンプルは、リンクした 2 番目の記事にあります。

あなたの場合、消費者が結果キューから物を拾い上げて、できるだけ早く処分することを望んでいると思います(ロギングストアなどに書き込みます)。

したがって、ログ項目をダンプする最終的なコレクションは、BlockingCollectionではなく である必要がありConcurrentQueueます。

于 2012-07-07T05:47:06.713 に答える