多个线程从Lookup读取<tkey,telement =“”>?</tkey,>是否安全?

时间:2012-03-20 16:42:18

标签: c# .net multithreading data-structures lookup

多个线程从Lookup<TKey, TElement>读取是否安全?

Lookup<TKey, TElement>是不可变的,但是MSDN表示:

  

此类型的任何公共静态(在Visual Basic中为Shared)成员都是   线程安全。任何实例成员都不能保证是线程   安全

虽然我不禁想象它,但我想知道机器是否抽出了MSDN文档  可能不正确。

4 个答案:

答案 0 :(得分:2)

因为我不喜欢冒险,我可能不得不在1年后调试一个模糊的多线程相关错误,我将假设在没有手动同步的情况下使用这个类是不安全的。

答案 1 :(得分:1)

只要没有写作,只做读取是线程安全的。这在任何情况下都是有效的。

您的问题在某种意义上与线程安全的概念正交。与写入或读取组合的写入不是线程安全的,但是没有写入的多次读取是线程安全的。

MSDN所说的实例成员不能保证是线程安全的,只有在非线程安全的情况下才有效,根据定义,这意味着写入操作。

答案 2 :(得分:0)

这是您可能注意到的 all 大多数课程的标准免责声明。某些方法可能是线程安全的,但“不保证”。

通常,如果没有集合的编写者,使用多个线程从集合中读取是安全的。如果您需要同时更新集合 - 使用适当的同步或内置线程安全集合,如SynchronizedKeyedCollection

答案 3 :(得分:0)

因为Lookup<TKey,TElement>是不可变的,意味着您将获得所有成员的相同值。这并不意味着无法修改存储在其中的项目。所以这个集合确实不是线程安全的。一个完美的例子是大多数linq是惰性求值的,创建枚举器可能涉及执行惰性代码。试图在两个单独的线程中进行枚举可能会导致集合被实现两次,从而产生错误的结果。

<强>更新 既然源代码在https://referencesource.microsoft.com上可用,则确认在方法调用期间设置内部状态而不考虑多线程意味着您可能具有竞争条件并且Lookup<TKey,TElement>类实际上不是线程安全的。