gpt4 book ai didi

c# - 阻止并发集合,例如 ConcurrentBag 或 BlockingCollection

转载 作者:太空宇宙 更新时间:2023-11-03 18:30:00 24 4
gpt4 key购买 nike

我想执行两个访问 ConcurrentBag 的语句,中间没有任何其他线程访问它。例如:

ConcurrentBag<int> concurrentBag = new ConcurrentBag<int>();
concurrentBag.Add(1);
int check = 0;
//Somehow block so that the following two statements will
//be executed without any other thread accessing concurrentBag.
concurrentBag.TryPeek(out check);
if (check == 2) concurrentBag.Add(3);

如何做到这一点?

最佳答案

我怀疑这比用 lock 关键字包装几行代码要困难得多。原因是您必须用锁包装对 ConcurrentBag所有 访问。如果你这样做了,那么它就不再是“并发的”了。我认为您要求的是一种暂时暂停集合的并发行为以支持序列化行为的方法,然后在完成特殊的 protected 操作后再次恢复其并发行为。

天真的方法是创建您自己的集合,通过在内部将其用作基础集合来提供与 ConcurrentBag 相同的操作。然后,您将提供 SuspendConcurrentResumeConcurrent 操作,通过设置和重置标志(可能通过 Interlocked.CompareExchange)切换集合的并发行为方法)。然后代码将使用此标志来确定是直接将 AddTryPeekTryTake 操作转发到基础集合还是使用硬锁在这样做之前。我认为最终您会发现代码非常复杂并且难以正确。根据个人经验,您现在设想的任何微不足道的实现都可能是错误的、低效的,或者在您希望的时候无法完全并发。

我的建议是找出一种方法来重构您的代码,以便消除此要求。

编辑:

从您的一条评论看来,您似乎想要一个 CAS like能够根据某事是否已经发生来做出决定的操作。有多种选择,但可能最适合您需要的一种是使用提供 TryAdd 方法的 ConcurrentDictionary 类。 TryAdd 如果键不存在则返回 true。如果 key 确实存在,那么它将返回 false。许多线程可以使用同一个键同时执行此方法,但只有一个线程会得到真正的响应。然后,您可以使用 if 语句根据返回值控制程序流。

关于c# - 阻止并发集合,例如 ConcurrentBag 或 BlockingCollection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24373936/

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