ICollection<> .Add()线程是否安全?

时间:2014-09-04 10:03:35

标签: c# collections concurrency thread-safety

我有如下收藏品?

public ICollection<MyClass> Property { get; private set; }
...
Property = new List<MyClass>();

我希望在从DB中获取每个MyClass项后,将Property项添加到MyClass中。现在,每个数据库提取都在单独的后台线程中处理,并且它们同时运行。因此,DB调用的每个返回值都将面向Property.Add()。现在这可能会导致竞争条件,因为Property.Add()可能会在一个瞬间被多次调用。

所以我的问题是List<>.Add()或任何其他实现ICollection<>.Add()的类在内部处理任何竞争条件还是需要明确处理?如果是,那怎么样?

3 个答案:

答案 0 :(得分:8)

ICollection没有任何内部结构;它是一个界面。实现可能是也可能不是线程安全的,但接口并不保证任何内容。

这可能有助于查看:

http://msdn.microsoft.com/en-us/library/dd997305%28v=vs.110%29.aspx

答案 1 :(得分:2)

您需要显式处理并发。这就是为什么有一个名称空间called System.Concurrent.Collections

如果顺序无关紧要,you might need to take a look to ConcurrentBag<T>.否则,您需要提供自己的实现或派生类,以便为任何开箱即用的ICollection<T>实现提供线程安全性在System.Collections.Generic命名空间中找到。

答案 2 :(得分:1)

您的具体类型为List<MyClass>,因此您应该查看List<T>.Add记录的List(T) Class的线程安全性:

  

线程安全

     

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

     

对List&lt; T&gt;执行多个读取操作是安全的,但如果在读取时修改了集合,则可能会出现问题。要确保线程安全,请在读取或写入操作期间锁定集合。要使多个线程可以访问集合以进行读写,您必须实现自己的同步。对于具有内置同步的集合,请参阅System.Collections.Concurrent命名空间中的类。有关固有的线程安全选择,请参阅ImmutableList类。

所以不,在您的具体示例中,它不是线程安全的,但可以通过使用不同的集合类型使其成为线程安全的。