- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
ConcurrentQueue
有 TryDequeue
方法。
Queue
只有 Dequeue
方法。
ConcurrentDictionary
中没有Add
方法,但我们有TryAdd
方法。
我的问题是:
这些并发收集方法有什么区别?为什么它们对于并发集合不同?
最佳答案
用Dictionary<TKey, TValue>
假定您要实现自己的逻辑以确保不输入重复键。例如,
if(!myDictionary.ContainsKey(key)) myDictionary.Add(key, value);
但是当我们有多个线程运行时,我们会使用并发集合,并且它们可能同时尝试修改字典。
如果两个线程试图同时执行上面的代码,有可能myDictionary.ContainsKey(key)
可能会为两个线程返回 false,因为它们同时进行检查并且尚未添加该 key 。然后他们都尝试添加 key ,但其中一个失败了。
阅读该代码但不知道它是多线程的人可能会感到困惑。在我添加它之前,我检查以确保该键不在字典中。。那么我如何获得异常呢?
ConcurrentDictionary.TryAdd
通过允许您“尝试”添加 key 来解决这个问题。如果它添加它返回的值 true
.如果不是,则返回 false
.但它不会做的是与另一个 TryAdd
发生冲突。并抛出异常。
您可以通过包装 Dictionary
来自己完成所有这些工作在类里面并投入lock
围绕它的语句以确保一次只有一个线程进行更改。 ConcurrentDictionary
只是为你做,而且做得很好。您不必查看其工作原理的所有详细信息 - 您只需在知道多线程已被考虑在内的情况下使用它即可。
这是在多线程应用程序中使用类时要查找的详细信息。如果您查看 ConcurrentDictionary Class 的文档滚动到底部你会看到这个:
Thread Safety
All public and protected members of ConcurrentDictionary are thread-safe and may be used concurrently from multiple threads. However, members accessed through one of the interfaces the ConcurrentDictionary implements, including extension methods, are not guaranteed to be thread safe and may need to be synchronized by the caller.
换句话说,多个线程可以安全地读取和修改集合。
下Dictionary Class你会看到这个:
Thread Safety
A Dictionary can support multiple readers concurrently, as long as the collection is not modified. Even so, enumerating through a collection is intrinsically not a thread-safe procedure. In the rare case where an enumeration contends with write accesses, the collection must be locked during the entire enumeration. To allow the collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization.
多个线程可以读取 key ,但是如果多个线程要写入 那么您需要以某种方式lock
确保一次只有一个线程尝试更新的字典。
Dictionary<TKey, TValue>
公开一个 Keys
收藏与Values
collection 以便您可以枚举键和值,但是如果另一个线程将要修改字典,它会警告您不要尝试这样做。在添加或删除项目时,您无法枚举某些内容。如果您需要遍历键或值,则必须锁定字典以防止在该迭代期间进行更新。
ConcurrentDictionary<TKey, TValue>
假设会有多个线程读写,所以它甚至不会公开键或值集合供您枚举。
关于c# - 为什么 ConcurrentQueue 和 ConcurrentDictionary 有 "Try"方法——TryAdd、TryDequeue——而不是 Add 和 Dequeue?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38396477/
我有一个并发字典,我用它来做一些线程安全的功能。 例如我有以下代码: var myConcurrenctDictionary= new ConcurrentDictionary(); if (myC
这更像是一个学术问题......但可以ConcurrentDictionary.TryAdd失败?如果是,在什么情况下以及为什么? 最佳答案 是的,这是条件(from msdn): ArgumentN
我一直在努力思考 Blocking Collection我遇到了 Take() 和 TryTake() 还有 Add() 和 TryAdd() 我知道如果没有要拿的元素,Take() 将等到元素被添加
我写了一个线程安全列表。但我还需要一种方法。具体来说,我需要一个带有第二个参数 -1 的方法,以便线程在必要时等待,并且元素刚刚进入集合。有一些代码: public sealed class Thre
来源有comment如果服务已在 IServiceCollection 中注册,则该 TryAdd 版本不会添加服务。但文档没有提到这个方法。什么时候应该使用它? 最佳答案 通常,如果您有一个具有依赖
当我调用 IProducerConsumerCollection.TryAdd()或 IProducerConsumerCollection.TryTake(out )这些会不会因为另一个线程正在使用
在 Azure.Messaging.EventHubs.Producer 命名空间中使用 EventDataBatch.TryAdd() 创建 EventDataBatch 时,如果事件数据对象的大小
ConcurrentQueue 有 TryDequeue 方法。 Queue 只有 Dequeue 方法。 ConcurrentDictionary 中没有Add 方法,但我们有TryAdd 方法。
我是一名优秀的程序员,十分优秀!