[英]ConcurrentDictionary<TKey,TValue> vs Dictionary<TKey,TValue>
ConcurrentDictionary<TKey, TValue>
Class Represents a thread-safe collection of key-value pairs that can be accessed by multiple threads concurrently. ConcurrentDictionary<TKey, TValue>
Class表示可以由多个线程同时访问的键值对的线程安全集合。
But as I know, System.Collections.Concurrent
classes are designed for PLINQ. 但据我所知,
System.Collections.Concurrent
类是为PLINQ设计的。
I have Dictionary<Key,Value>
which keeps on-line clients in the server, and I make it thread safe by locking object when I have access to it. 我有
Dictionary<Key,Value>
,它保留了服务器中的在线客户端,并且当我有权访问它时,我通过锁定对象使其成为线程安全的。
Can I safely replace Dictionary<TKey,TValue>
by ConcurrentDictionary<TKey,TValue>
in my case? 在我的情况下,我可以通过
ConcurrentDictionary<TKey,TValue>
安全地替换Dictionary<TKey,TValue>
吗? will the performance increased after replacement? 更换后性能会提高吗?
Here in Part 5 Joseph Albahari mentioned that it designed for Parallel programming 这里在第5约瑟夫阿尔巴哈利提到,它专为并行编程
Without knowing more about what you're doing within the lock, then it's impossible to say. 如果不知道你在锁中做了什么,那就不可能说了。
For instance, if all of your dictionary access looks like this: 例如,如果您的所有字典访问都如下所示:
lock(lockObject)
{
foo = dict[key];
}
... // elsewhere
lock(lockObject)
{
dict[key] = foo;
}
Then you'll be fine switching it out (though you likely won't see any difference in performance, so if it ain't broke, don't fix it). 然后你可以将它切换出来(虽然你可能不会看到性能上的任何差异,所以如果没有破坏,不要修复它)。 However, if you're doing anything fancy within the lock block where you interact with the dictionary, then you'll have to make sure that the dictionary provides a single function that can accomplish what you're doing within the lock block, otherwise you'll end up with code that is functionally different from what you had before.
但是,如果您在与字典交互的锁定块中执行任何操作,那么您必须确保字典提供单个函数,该函数可以完成您在锁定块中所执行的操作,否则您最终会得到与以前功能不同的代码。 The biggest thing to remember is that the dictionary only guarantees that concurrent calls to the dictionary are executed in a serial fashion;
要记住的最重要的事情是字典只保证对字典的并发调用以串行方式执行; it can't handle cases where you have a single action in your code that interacts with the dictionary multiple times.
它无法处理您的代码中有多个与字典交互的单个操作的情况。 Cases like that, when not accounted for by the
ConcurrentDictionary
, require your own concurrency control. 这样的情况,当不被
ConcurrentDictionary
,需要你自己的并发控制。
Thankfully, the ConcurrentDictionary
provides some helper functions for more common multi-step operations like AddOrUpdate
or GetOrAdd
, but they can't cover every circumstance. 值得庆幸的是,
ConcurrentDictionary
为更常见的多步操作(如AddOrUpdate
或GetOrAdd
提供了一些辅助函数,但它们无法涵盖所有情况。 If you find yourself having to work to shoehorn your logic into these functions, it may be better to handle your own concurrency. 如果你发现自己不得不把你的逻辑搞砸到这些函数中,那么处理你自己的并发可能会更好。
It's not as simple as replacing Dictionary
with ConcurrentDictionary
, you'll need to adapt your code, as these classes have new methods that behave differently, in order to guarantee thread-safety. 它不像用
ConcurrentDictionary
替换Dictionary
那么简单,你需要调整你的代码,因为这些类有新的方法行为不同,以保证线程安全。
Eg., instead of calling Add
or Remove
, you have TryAdd
and TryRemove
. 例如,而不是调用
Add
或Remove
,你有TryAdd
和TryRemove
。 It's important you use these methods that behave atomically, as if you make two calls where the second is reliant on the outcome of the first, you'll still have race conditions and need a lock
. 重要的是你使用这些原子行为的方法,就像你进行两次调用,其中第二次依赖于第一次的结果,你仍然会有竞争条件并需要
lock
。
You can replace Dictionary<TKey, TValue>
with ConcurrentDictionary<TKey, TValue>
. 您可以使用
ConcurrentDictionary<TKey, TValue>
替换Dictionary<TKey, TValue>
ConcurrentDictionary<TKey, TValue>
。
The effect on performance may not be what you want though (if there is a lot of locking/synchronization, performance may suffer...but at least your collection is thread-safe). 对性能的影响可能不是你想要的(如果有很多锁定/同步,性能可能会受到影响......但至少你的集合是线程安全的)。
While I'm unsure about replacement difficulties, but if you have anywhere where you need to access multiple elements in the dictionary in the same "lock session" then you'll need to modify your code. 虽然我不确定替换困难,但如果你有任何地方需要在相同的“锁定会话”中访问字典中的多个元素,那么你将需要修改你的代码。
It could give improved performance if Microsoft has given separate locks for read and write, since read operations shouldn't block other read operations. 如果Microsoft为读写提供了单独的锁,它可以提高性能,因为读操作不应该阻止其他读操作。
Yes you can safely replace, however dictionary designed for plinq may have some extra code for added functionality that you may not use. 是的,您可以安全地替换,但是为plinq设计的字典可能有一些额外的代码,用于添加您可能不使用的功能。 But the performance overhead will be marginally very small.
但性能开销将略微很小。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.