2011-08-23 6 views
8

私はWindowsフォームアプリケーション(C#)を開発していますが、プログラムの実行中はオブジェクトを作成してリストに追加します。リスト内のアイテムをFIFO(先入れ先出し)で処理する必要があります。私はbackgroundthreadでこれをしたいと思います。私はそれらを1番、2番、3番の順に処理しなければなりません。そして、アイテムがリストに追加されるとすぐに、それを処理したいと思います。だから私はそのリストをチェックする何かを持っている必要があります。ジョブのBlockingCollectionまたはQueue <T>?

これを達成する最も良い方法は何ですか?

blockingcollectionは、処理する前にアイテムが追加されるのを待つという点で、同じようなことをしています。

私はキューを持つ単一のスレッドを使用することができます(真)とアイテムがあればそれを取る?

あなたはどう思いますか?

答えて

14

バックグラウンドスレッドを使用する予定がある場合は、BlockingCollection<T>に行ってください。同じwhile(true)ロジックを簡単に実行することができます。

BlockingCollection<T>はあなたので、あなたのための2つの重要な機能

  1. それはスレッドセーフあなたはTake()を呼び出すと、それはブロックします

  2. (つまり、何かがキューにあるまで待つ)だを与えますManualResetEventsなどのコードを書く必要はありません。これはすばらしい単純化です。キューが空の場合はブロックする場合

+0

はい、正確です! – syncis

+2

@Jonathan Beerhalter:または、「Take」を呼び出す代わりに、バックグラウンドスレッドで[forex'を[GetConsumingEnumerable']にするだけでよいのですが、これは私の考えを確認するものです。 (http://msdn.microsoft.com/en-us/library/dd287186.aspx)、 'BlockingCollection 'に配置されているアイテムを生成します。 – casperOne

+0

@ sync: 'GetConsumingEnumerable'は' Take'のように 'BlockingCollection 'に項目が追加されるまでブロックします。問題は、あなたのバックグラウンドスレッドはこれらのアイテムを処理する以外に何をしているのですか?スレッドを保存しようとしている場合。基本的にスレッドプールを書き直しているのですが、それは一般的には良い考えではありません。あなたのアイテムを1つずつ処理している間に、より多くのアイテムが 'Take'のために来るか、GetConsumingEnumerableによって生成されることに注意してください(必要に応じて、他のスレッドで処理するアイテムを送ることができます)。 – casperOne

0

その後、BlockingCollectionを使用する - それは理想的です... をあなたはそれがより多くのキューのような、その後ConcurrentQueueを(どのように空に対処するために自分自身を決める)したい場合。

の両方がConcurrentQueueほとんどの操作では、スレッドセーフであるロックフリー...いずれかの方法は、それを直接使用するか、または例えば、BlockingCollection<string> = new BlockingCollection<string> (new ConcurrentQueue<string>)のためのあなたのBlockingCollectionの基本型ほど本当に速い実装されている - あなたも最大capactiyを置くことができますそれ(コンストラクタのオプションの2番目のパラメータ)。

関連する問題