c# - IEnumerable Linq 方法是线程安全的吗?

标签 c# multithreading thread-safety atomic

我想知道 Linq 扩展方法是否是原子的?或者我是否需要在任何类型的迭代之前锁定跨线程使用的任何IEnumerable 对象?

将变量声明为 volatile 对此有任何影响吗?

总而言之,以下哪项是最好的线程安全操作?

1- 没有任何锁:

IEnumerable<T> _objs = //...
var foo = _objs.FirstOrDefault(t => // some condition

2- 包括锁定语句:

IEnumerable<T> _objs = //...
lock(_objs)
{
    var foo = _objs.FirstOrDefault(t => // some condition
}

3- 将变量声明为 volatile:

volatile IEnumerable<T> _objs = //...
var foo = _objs.FirstOrDefault(t => // some condition

最佳答案

界面IEnumerable<T>不是线程安全的。请参阅 http://msdn.microsoft.com/en-us/library/s793z9y2.aspx 上的文档,其中指出:

An enumerator remains valid as long as the collection remains unchanged. If changes are made to the collection, such as adding, modifying, or deleting elements, the enumerator is irrecoverably invalidated and its behavior is undefined.

The enumerator does not have exclusive access to the collection; therefore, enumerating through a collection is intrinsically not a thread-safe procedure. To guarantee thread safety during enumeration, you can lock the collection during the entire enumeration. To allow the collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization.

Linq 不会改变任何这些。

显然可以使用锁定来同步对对象的访问。但是,您必须在访问它的任何地方锁定该对象,而不仅仅是在迭代它时。

将集合声明为 volatile 不会产生任何积极影响。它只会在读取集合引用之前和写入集合引用之后导致内存屏障。它不同步集合读取或写入。

关于c# - IEnumerable Linq 方法是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11103779/

相关文章:

c# - 找不到类型或命名空间名称 'HttpResponseMessage'

java - swing中Timer和TimerTask的区别

c# - 我是否需要在 ASP.NET 中配置 Web 服务引用?

c# - 使用工厂方法创建子类对象

c# - Windows 窗体上的 log4net 不写入日志文件

python - 这是子类化 python 线程以接受变量更新的有效方法吗?

java - 如何同步多线程 map 更新

.net - 跨多个线程管理状态

c# - 在没有同步的情况下修改可为空的 DateTimeOffset 字段是否线程安全

java - 如何破坏这个(非?)线程安全对象?