11

C# では、BlockingCollection がバックグラウンド スレッドによってクリアされるまで待機することが可能かどうか疑問に思っています。時間がかかりすぎる場合はタイムアウトします。

現時点で私が持っている一時的なコードは、やや洗練されていないように思えます (いつから使用するのが良い習慣なのThread.Sleepでしょうか?):

while (_blockingCollection.Count > 0 || !_blockingCollection.IsAddingCompleted)
{
    Thread.Sleep(TimeSpan.FromMilliseconds(20));
    // [extra code to break if it takes too long]
}
4

3 に答える 3

6

消費スレッドで次のように書いたらどうなるでしょうか。

var timeout = TimeSpan.FromMilliseconds(10000);
T item;
while (_blockingCollection.TryTake(out item, timeout))
{
     // do something with item
}
// If we end here. Either we have a timeout or we are out of items.
if (!_blockingCollection.IsAddingCompleted)
   throw MyTimeoutException();
于 2014-01-07T13:51:47.357 に答える
3

コレクションが空のときにイベントを設定できるように再設計できる場合は、コレクションが空になるまで待機ハンドルを使用できます。

static void Main(string[] args)
{
    BlockingCollection<int> bc = new BlockingCollection<int>();
    ManualResetEvent emptyEvent = new ManualResetEvent(false);
    Thread newThread = new Thread(() => BackgroundProcessing(bc, emptyEvent));
    newThread.Start();
    //wait for the collection to be empty or the timeout to be reached.
    emptyEvent.WaitOne(1000);

}
static void BackgroundProcessing(BlockingCollection<int> collection, ManualResetEvent emptyEvent)
{
    while (collection.Count > 0 || !collection.IsAddingCompleted)
    {
        int value = collection.Take();
        Thread.Sleep(100);
    }
    emptyEvent.Set();
}
于 2014-01-07T13:51:35.880 に答える