gpt4 book ai didi

c# - 如何访问阻塞集合的底层默认并发队列

转载 作者:太空狗 更新时间:2023-10-29 20:59:39 32 4
gpt4 key购买 nike

我有多个生产者和一个消费者。然而,如果队列中有一些东西还没有被消费,生产者不应该再把它排队。 (使用默认并发队列的唯一无重复阻塞集合)

if (!myBlockingColl.Contains(item))
myBlockingColl.Add(item)

然而,阻塞式 coll 没有 contains 方法,也没有提供任何类型的 trypeek() 之类的方法。我怎样才能访问底层的并发队列,这样我就可以做类似的事情

if (!myBlockingColl.myConcurQ.trypeek(item)
myBlockingColl.Add(item)

尾部旋转。请帮忙。谢谢

最佳答案

这是一个有趣的问题。这是我第一次看到有人要求忽略重复的阻塞队列。奇怪的是,我找不到 BCL 中已经存在的任何东西。我说这很奇怪,因为 BlockingCollection 可以接受 IProducerConsumerCollection 作为基础集合,它具有 TryAdd 方法,该方法被宣传为能够在以下情况下失败检测到重复项。问题是我没有看到防止重复的 IProducerConsumerCollection 的具体实现。至少我们可以自己写。

public class NoDuplicatesConcurrentQueue<T> : IProducerConsumerCollection<T>
{
// TODO: You will need to fully implement IProducerConsumerCollection.

private Queue<T> queue = new Queue<T>();

public bool TryAdd(T item)
{
lock (queue)
{
if (!queue.Contains(item))
{
queue.Enqueue(item);
return true;
}
return false;
}
}

public bool TryTake(out T item)
{
lock (queue)
{
item = null;
if (queue.Count > 0)
{
item = queue.Dequeue();
}
return item != null;
}
}
}

现在我们有了不接受重复项的 IProducerConsumerCollection,我们可以像这样使用它:

public class Example
{
private BlockingCollection<object> queue = new BlockingCollection<object>(new NoDuplicatesConcurrentQueue<object>());

public Example()
{
new Thread(Consume).Start();
}

public void Produce(object item)
{
bool unique = queue.TryAdd(item);
}

private void Consume()
{
while (true)
{
object item = queue.Take();
}
}
}

您可能不喜欢我的 NoDuplicatesConcurrentQueue 实现。如果您认为需要 TPL 集合提供的低锁性能,您当然可以使用 ConcurrentQueue 或任何其他方式自由实现您自己的。

更新:

今天早上我能够测试代码。有一些好消息和坏消息。好消息是这在技术上是可行的。坏消息是您可能不想这样做,因为 BlockingCollection.TryAdd 拦截了底层 IProducerConsumerCollection.TryAdd 方法的返回值,并在 时抛出异常false 被检测到。是的,没错。它不会像您期望的那样返回 false 而是生成一个异常。老实说,这既令人惊讶又可笑。 TryXXX 方法的全部意义在于它们不应抛出异常。我深感失望。

关于c# - 如何访问阻塞集合的底层默认并发队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6603969/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com