How to empty a BlockingCollection

2019-04-04 03:53发布

I have a thread adding items to a BlockingCollection .

On another thread I am using foreach (var item in myCollection.GetConsumingEnumerable())

If there is a problem I want to break out of my foreach and my method and clear whatever is left in the BlockingCollection however I can't find a way to do it.

Any ideas?

6条回答
再贱就再见
2楼-- · 2019-04-04 04:25

I'm using this extension method:

public static void Clear<T>(this BlockingCollection<T> blockingCollection)
{
    if (blockingCollection == null)
    {
        throw new ArgumentNullException("blockingCollection");
    }

    while (blockingCollection.Count > 0)
    {
        T item;
        blockingCollection.TryTake(out item);
    }
}

I'm wondering if there's a better, less hacky, solution.

查看更多
霸刀☆藐视天下
3楼-- · 2019-04-04 04:27

Just take out all remaining items:

while (collection.TryTake(out _)){}
查看更多
小情绪 Triste *
4楼-- · 2019-04-04 04:27

Possibly use the overload of GetConsumingEnumerable which takes a CancellationToken, and then if anything goes wrong from the producing side, it can cancel the consumer.

查看更多
太酷不给撩
5楼-- · 2019-04-04 04:30
BlockingCollection<T> yourBlockingCollection = new BlockingCollection<T>();

I assumed you mean clear your blocking collection. Jon's answer is more appropriate to your actual question I think.

查看更多
Emotional °昔
6楼-- · 2019-04-04 04:38

This worked for me

while (bCollection.Count > 0)
{
    var obj = bCollection.Take();
    obj.Dispose();
}

Take() removes from the collection and you can call any clean up on your object and the loop condition does not invoke any blocking calls.

查看更多
叛逆
7楼-- · 2019-04-04 04:44

For just clearing the collection you can do:

myBlockingCollection.TakeWhile<*MyObject*>(qItem => qItem != null);

or just

myBlockingCollection.TakeWhile<*MyObject*>(qItem => true);
查看更多
登录 后发表回答