gpt4 book ai didi

c# - 在 BlockingCollection 上调用 Dispose

转载 作者:可可西里 更新时间:2023-11-01 09:06:29 25 4
gpt4 key购买 nike

我在 Albahari (http://www.albahari.com/threading/part5.aspx#_BlockingCollectionT) 的 Nutshell 书中重用了 C# 中的示例生产者消费者队列,一位同事评论道:“为什么不在集合的 Dispose 中对 BlockingCollection 调用 Dispose?”

我找不到答案,我能想到的唯一原因是队列剩余工作负载的执行不会被处理。但是,当我处理队列时,为什么它不会停止处理?

除了“为什么你不应该处理 BlockingCollection?”我还有第二个问题“如果不处理 BlockingCollection 会有害吗?”。我想当你产生/处理大量生产者消费者队列时它会带来问题(不是我想要的,但只是为了知道的原因)。根据What does BlockingCollection.Dispose actually do? BlockingCollection 包含两个等待句柄(显然),因此不调用 Dispose 会给您带来一些问题。感谢 ken2k 指出这一点。

我正在谈论的代码:

public class PCQueue : IDisposable
{
BlockingCollection<Action> _taskQ = new BlockingCollection<Action>();
public PCQueue (int workerCount)
{
// Create and start a separate Task for each consumer:
for (int i = 0; i < workerCount; i++)
Task.Factory.StartNew (Consume);
}

public void Dispose() { _taskQ.CompleteAdding(); }

public void EnqueueTask (Action action) { _taskQ.Add (action); }

void Consume()
{
// This sequence that we’re enumerating will block when no elements
// are available and will end when CompleteAdding is called.
foreach (Action action in _taskQ.GetConsumingEnumerable())
action(); // Perform task.
}
}

最佳答案

因为那会是一个错误。在所有使用者线程退出之前,无法处置该集合。如果那不是互锁的,那么这些线程将因异常而爆炸。该类根本不知道哪些消费者线程可能从集合中提取,因此它无法合理地知道何时可以安全处置。它所能做的就是阻止生产者添加更多对象,这是合理的。

这是线程的常见问题,安全处置需要知道线程何时完成。这通常首先会破坏使用线程的意义,您不想等到线程结束。这在 Thread 类本身中最为明显,它使用五个 native 操作系统句柄但没有 Dispose() 方法。它们需要由终结器释放。这里也一样。

关于c# - 在 BlockingCollection<T> 上调用 Dispose,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9428718/

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