- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想执行两个访问 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
相同的操作。然后,您将提供 SuspendConcurrent
和 ResumeConcurrent
操作,通过设置和重置标志(可能通过 Interlocked.CompareExchange
)切换集合的并发行为方法)。然后代码将使用此标志来确定是直接将 Add
、TryPeek
和 TryTake
操作转发到基础集合还是使用硬锁在这样做之前。我认为最终您会发现代码非常复杂并且难以正确。根据个人经验,您现在设想的任何微不足道的实现都可能是错误的、低效的,或者在您希望的时候无法完全并发。
我的建议是找出一种方法来重构您的代码,以便消除此要求。
编辑:
从您的一条评论看来,您似乎想要一个 CAS like能够根据某事是否已经发生来做出决定的操作。有多种选择,但可能最适合您需要的一种是使用提供 TryAdd
方法的 ConcurrentDictionary
类。 TryAdd
如果键不存在则返回 true。如果 key 确实存在,那么它将返回 false。许多线程可以使用同一个键同时执行此方法,但只有一个线程会得到真正的响应。然后,您可以使用 if
语句根据返回值控制程序流。
关于c# - 阻止并发集合,例如 ConcurrentBag 或 BlockingCollection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24373936/
我一直在阅读新的并发集合,特别是 ConcurrentBag 引起了我的注意。由于 ConcurrentBag 内部在每个单独的线程上持有一个本地集,使用它来跟踪项目,这意味着当线程本身超出范围时,它
"ConcurrentBag(T) is a thread-safe bag implementation, optimized for scenarios where the same thread
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Possible memoryleak in ConcurrentBag? 我的应用中出现严重内存泄漏。我使
我正在运行一些使用 ConcurrentBags 的代码。我正在探索 IEnumerable 功能。我运行的代码是 ConcurrentBag bag = new ConcurrentBag(); T
.NET 4.5.1 我有一个包含 200,000 个对象的 ConcurrentBag。一个对象被两个 long 类型的属性认为是“唯一的”。 我需要检查包中是否存在以前存在的唯一对象,如果不存在,
我有一个 .NET 4.5 单实例 WCF 服务,它维护列表中的项目集合,该列表将同时具有并发的读者和作者,但读者比作者多得多。 我目前正在决定是否使用 BCL ConcurrentBag或使用我自己
有没有办法一次将多个项目添加到 ConcurrentBag,而不是一次添加一个?我没有在 ConcurrentBag 上看到 AddRange() 方法,但是有一个 Concat()。但是,这对我不起
我已经在这里阅读了之前关于 ConcurrentBag 的问题但没有找到在多线程中的实际实现示例。 ConcurrentBag is a thread-safe bag implementation,
分析后,我发现我的应用程序中的特定对象将通过使用对象池而不是构造对象池而受益匪浅。此应用程序基于具有多个线程的生产者/消费者队列。 ConcurrentBag 集合基本上是一个对象池,作为应用程序对象
我在使用包含非托管对象的 ConcurrentBag 正确处理 Dispose/Finalization 时遇到问题。运行下面的代码(通常)会在对 TryTake(). 大概在这种情况下,垃圾收集器在
我需要将 ConcurrentBag 设置为可通知的。我需要知道它安全吗?该类的代码是 public class NotifiableConcurrentBag : ConcurrentBag, IN
我有一个静态集合,比如调用远程 rest api 的任务: static ConcurrentBag> _collection = new ConcurrentBag>(); static void
我读到要修改或改变并发包中的对象,我必须将其取出、修改,然后再放回去。 但是,我看到了执行以下操作的代码: var obj = bag.FirstOrDefault(report => report.
当线程添加或删除 ConcurrentBag 的元素时会发生什么而另一个线程正在枚举这个包?新元素是否也会出现在枚举中,删除的元素是否不会出现? 最佳答案 一 jar read the fine ma
我编写了一个程序,其中列表构建器方法返回 IEnumerable of string,其中包括大量字符串(100 万个项目),我将其存储在 List of string 中,然后它将所有项目附加到 中
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Possible memoryleak in ConcurrentBag? 编辑1: 真正的问题是。你能证实
我已经构建了这段代码来并行处理大量字符串之间的字符串比较,以加快速度。 我使用了 ConcurrentBag,因此所有线程(任务)都可以写入线程安全集合。然后我将这个集合转储到一个文件中。 我遇到的问
我有一个应用程序,它有一个存储在 static ConcurrentBag 中的对象列表。 UI 有一个计时器,它运行的方法可以更新 ConcurrentBag 中的对象。 只有一个线程(由计时器启动
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T
如何清除ConcurrentBag?它没有任何方法,如 Clear 或 RemoveAll... 最佳答案 2017 年 10 月 3 日更新:正如@Lou 正确指出的那样,赋值是原子的。在这种情况下
我是一名优秀的程序员,十分优秀!