我有如下收藏品?
public ICollection<MyClass> Property { get; private set; }
...
Property = new List<MyClass>();
我希望在从DB中获取每个MyClass
项后,将Property
项添加到MyClass
中。现在,每个数据库提取都在单独的后台线程中处理,并且它们同时运行。因此,DB调用的每个返回值都将面向Property.Add()
。现在这可能会导致竞争条件,因为Property.Add()
可能会在一个瞬间被多次调用。
所以我的问题是List<>.Add()
或任何其他实现ICollection<>.Add()
的类在内部处理任何竞争条件还是需要明确处理?如果是,那怎么样?
答案 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类。
所以不,在您的具体示例中,它不是线程安全的,但可以通过使用不同的集合类型使其成为线程安全的。