2017-09-05 35 views
-2

我有一个方法:将ConcurrentDictionary类型传递给一个需要IDictionary的函数是否安全?

void foo(IDictionary<string, object> data) { 
    data["key1"] = getValue1(); 
    data["key2"] = getValue2(); 
} 

我现在把它叫做如下:

var serialDict = new Dictionary<string, object>(); 
foo(serialDict); 

现在我需要调用fooConcurrentDictionary类型,因为字典正在对多线程进行填充。

var concurrentDict = new Dictionary<string, object>(); 
foo(concurrentDict); 

由于ConcurrentDictionary器具IDictionary,我没有改变foo方法的签名。而且这一改变似乎在我的机器上运行良好。

但是,有些东西并不适合我,因为能够以相同的方式/方法填充常规字典和并发字典。

我在做什么安全?

+0

我不明白为什么它不会好。 Concurrent Dict表示,它可以用于IDictionary的任何地方 - 它通过实现该接口来说明。 – pm100

+3

什么操作下的“安全”?你的程序是在一个线程上添加这些键并在另一个线程上读取它们?你有订阅要求,读者在作家后面跑?因为这些不变量不是由您的代码维护的。在竞争条件下,并发字典**不会使您的进程**崩溃,但这并不意味着您的程序自动*正确*!你必须把字典看作*不断变化*,除非你编写了能够保持它不变的代码。 –

+0

@EricLippert不是那些相同的键,我有订购说明。其他线程添加或编辑键,但不是这种方法中的键。 – AngryHacker

回答

1

这取决于你在方法中做了什么,如果你只是使用索引操作修改字典,它应该没问题,因为索引设置的语义是添加或更新,字典应该在线程安全方式。 如果您的方法执行更复杂的操作,例如检查键的存在,然后在不存在的情况下添加值,那么如果多个线程正在写入字典,则可能会导致意外的结果(ConcurrentDictionary有专用的重载或创建原子的值)

如果将方法添加到字典中,然后期望从字典中读取值并且另一个线程修改相同的密钥,则您的方法也可能会感到困惑。

所以简短的回答是,通常应该没问题,但是如果该方法不是在考虑线程安全的情况下创建的,则需要分析并发问题的方法。

相关问题