.NET 4.0 BlockingCollectionを使用して、各アイテムを処理するのに最大1秒かかる処理で処理する必要があるアイテムのキューを処理しています。このアイテムのキューは、異なるスレッドによって追加できます。複数のコンシューマとC#BlockingCollectionのクエリ
私はこのことに関するいくつかの質問があります。 a)複数の消費者がこのBlockingCollectionで作業できるようにしますか?私はGetConsumingEnumerable()を気付きました。これは単一のコンシューマシナリオに適用されるようです。複数のコンシューマを持つ理由は、名前付きパイプのインスタンスを使用して処理すると、同時に3つまでのアイテムを処理できるため、3つのコンシューマを持つことができると考えました。
b)アイテムがこのキューにあるかどうかを確認する方法はありますか?そうであれば、アイテムが処理されるまでブロックするアイテムがあるかどうかを確認する呼び出し元を取得しますか?
EDIT:ジョンスキートの答えに基づいて
がここで消費者がGetConsumingEnumerable()
を使用して、1つのプロデューサによって移入BlockingCollectionに作用する複数のコンシューマを説明するためにいくつかのサンプルコードです:
static BlockingCollection<string> coll = new BlockingCollection<string>();
static void Consume()
{
foreach (var i in coll.GetConsumingEnumerable())
{
Console.WriteLine(String.Format("Thread {0} Consuming: {1}", Thread.CurrentThread.ManagedThreadId, i));
Thread.Sleep(1000);
}
}
static void Main(string[] args)
{
int item = 0;
Task.Factory.StartNew(() =>
{
while (true)
{
coll.Add(string.Format("Item {0}", item++));
Thread.Sleep(500);
}
});
for (int i = 0; i < 2; i++)
{
Task.Factory.StartNew(() => Consume());
}
while (true) ;
}
項目がされています2つの異なるスレッド上で動作する2つのコンシューマ間でインタリーブされたやり方で処理される。
Thread 4 Consuming: Item 0
Thread 5 Consuming: Item 1
Thread 4 Consuming: Item 2
Thread 5 Consuming: Item 3
Thread 4 Consuming: Item 4
...しかし、あなたの2番目の質問に従わなかった - それは、2回目の読み出しに少し漠然としたようです。だから問題は、アイテムがキューに登録されているかどうかを調べることができるようにすることです(私はちょうどこれをチェックするためにlinqクエリを書くことができます)ので、キューに重複したアイテムを追加しません重複処理)。このキューは、名前付きパイプを介したPDFライターへの入力であり、PDFを共有ロケーションに書き込みます。 – pkiddie
これで、すでにキューに入っているアイテムがリクエストされた場合(つまり、私が書いたHttpHandlerによって)、アイテムが処理されるまでHttpHandlerの呼び出し要求をブロックして、そのタスクがPDFファイルはディスクに保存されています。 コンテキストを有効にすることができます。 – pkiddie
@pkiddie:アイテムがすでに処理されているかどうかも知りたくありませんか? –