gpt4 book ai didi

c# - 不为空时处理 ConcurrentStack?

转载 作者:行者123 更新时间:2023-11-30 14:09:13 30 4
gpt4 key购买 nike

我有一个 ConcurrentStack,我正在向其中倾倒项目。当堆栈不为空时,一次处理这些项目的好方法是什么?我希望以一种在未处理堆栈时不会占用 CPU 周期的方式来执行此操作。

我目前得到的基本上就是这个,它似乎不是一个理想的解决方案。

private void AddToStack(MyObj obj)
{
stack.Push(obj);
HandleStack();
}

private void HandleStack()
{
if (handling)
return;

Task.Run( () =>
{
lock (lockObj)
{
handling = true;
if (stack.Any())
{
//handle whatever is on top of the stack
}
handling = false;
}
}
}

所以 bool 在那里,所以多个线程不会在等待锁时被备份。但我不希望同时处理堆栈的多个事物因此锁定。因此,如果两个单独的线程确实最终同时调用 HandleStack 并通过 bool,那么锁就在那里,因此两个线程不会同时遍历堆栈。但是一旦第二个通过锁,堆栈将是空的并且不做任何事情。所以这最终确实给了我想要的行为。

所以实际上我只是围绕 ConcurrentStack 编写一个伪并发包装器,看起来必须有一种不同的方法来实现这一点。想法?

最佳答案

ConcurrentStack<T>是实现 IProducerConsumerCollection<T> 的集合之一,因此可以用 BlockingCollection<T> 包裹. BlockingCollection<T>有几个方便的成员用于常见操作,如“在堆栈不为空时消费”。例如,您可以调用 TryTake在一个循环中。或者,您可以只使用 GetConsumingEnumerable :

private BlockingCollection<MyObj> stack;
private Task consumer;

Constructor()
{
stack = new BlockingCollection<MyObj>(new ConcurrentStack<MyObj>());
consumer = Task.Run(() =>
{
foreach (var myObj in stack.GetConsumingEnumerable())
{
...
}
});
}

private void AddToStack(MyObj obj)
{
stack.Add(obj);
}

关于c# - 不为空时处理 ConcurrentStack?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30531602/

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