从BlockingCollection中移除一个项目

12

如何从 BlockingCollection 中移除一个元素?以下哪种方法是正确的?

myBlockingCollection.Remove(Item);
或者
myBlockingCollection.Take(Item);
4个回答

12
您无法指定从BlockingCollection<T>中删除特定项。 Take()方法从基础集合中移除一项并返回已删除的项。 TryTake(out T item)方法从基础集合中移除一项并将已删除的项分配给out参数。如果可以删除项目,则该方法返回true;否则返回false。
被删除的项取决于BlockingCollection<T>所使用的基础集合 - 例如,ConcurrentStack<T>将具有LIFO行为,而ConcurrentQueue<T>将具有FIFO行为。

5
这段代码怎么样? - 它能正常工作,但需要改变集合的顺序。(我没有在多线程状态下进行检查)
public static bool Remove<T>(this BlockingCollection<T> self, T itemToRemove)
    {
        lock (self)
        {
            T comparedItem;
            var itemsList = new List<T>();
            do
            {
                var result = self.TryTake(out comparedItem);
                if (!result)
                    return false;
                if (!comparedItem.Equals(itemToRemove))
                {
                    itemsList.Add(comparedItem);
                }
            } while (!(comparedItem.Equals(itemToRemove)));
            Parallel.ForEach(itemsList, t => self.Add(t));
        }
        return true;
    }

这样做的麻烦之处在于集合上的其他方法都不会锁定self。例如,如果另一个线程在创建itemsList后添加了一个新项,会发生什么? - Tony Edgecombe

2

我认为只有TryTake()是一个选项?我在MSDN上找不到Remove()方法的文档。

(Note: No changes made to HTML tags)

-1

我认为 TryTake(out item) 可以工作。BlockingCollection 类中不存在 Remove 方法,而 Take 方法也不接受 item 作为参数。


1
TryTake(out item) 不像 Remove(item) 那样指定要删除哪个项目。没有等价物。 - pauldendulk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接