2011-09-23 11 views
13

.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 

答えて

10

複数の消費者はただ同時にTakeTryTakeを呼び出すことができます - 各項目は、単一の消費者によって消費されます。

しかし、私は信じていますGetConsumingEnumerableあなたがしたいこともします。私は、それぞれの呼び出し元がそれを呼び出すと、それぞれが個別の列挙型を取得し、各項目が1回だけ消費されることを確認すると考えられます。キューが空になったときに何が起こるのかわからない。MoveNext()がブロックするか、falseを返すかわからない。

私は本当に申し訳ありません

+0

...しかし、あなたの2番目の質問に従わなかった - それは、2回目の読み出しに少し漠然としたようです。だから問題は、アイテムがキューに登録されているかどうかを調べることができるようにすることです(私はちょうどこれをチェックするためにlinqクエリを書くことができます)ので、キューに重複したアイテムを追加しません重複処理)。このキューは、名前付きパイプを介したPDFライターへの入力であり、PDFを共有ロケーションに書き込みます。 – pkiddie

+0

これで、すでにキューに入っているアイテムがリクエストされた場合(つまり、私が書いたHttpHandlerによって)、アイテムが処理されるまでHttpHandlerの呼び出し要求をブロックして、そのタスクがPDFファイルはディスクに保存されています。 コンテキストを有効にすることができます。 – pkiddie

+0

@pkiddie:アイテムがすでに処理されているかどうかも知りたくありませんか? –

関連する問題