Являются ли методы IEnumerable Linq поточно-ориентированными?

Интересно, являются ли методы расширения Linq атомарными? Или мне нужноlock любойIEnumerable Объект используется в потоках, перед любой итерацией?

Объявляет переменную какvolatile иметь какое-либо влияние на это?

Подводя итог, какая из следующих операций является лучшей, поточно-ориентированной операцией?

1- Without any locks:

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

2- Including lock statements:

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

3- Declaring variable as volatile:

volatile IEnumerable<T> _objs = //...
var foo = _objs.FirstOrDefault(t => // some condition
 stuartd19 июн. 2012 г., 17:04
Они не безопасны. Увидетьstackoverflow.com/questions/9995266/…

Ответы на вопрос(2)

они не являются поточно-ориентированными, как указано выше.

Однако это не означает, что вы должны заблокировать перед «каждым видом итерации».

Вам необходимо синхронизировать все операции, которые изменяют коллекцию (добавлять, изменять или удалять элементы), с другими операциями, которые (добавлять, изменять, удалять элементы или читать элементы).

Если вы одновременно выполняете только операции чтения в коллекции, блокировка не требуется. (поэтому все команды LINQ, такие как Average, Contains, ElementAtOrDefault, все в порядке)

Если элементы в коллекции имеют длину машинного слова, например Int на большинстве 32-разрядных компьютеров, то изменение значения этого элемента уже выполняется атомарно. В этом случае не добавляйте и не удаляйте элементы из коллекции без блокировки, но изменение значений может быть приемлемым, если вы можете справиться с недетерминизмом в своем дизайне.

Наконец, вы можете рассмотреть возможность детальной блокировки отдельных элементов или разделов коллекции, а не блокировки всей коллекции.

Решение Вопроса

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 не меняет ничего из этого.

Блокировка, очевидно, может использоваться для синхронизации доступа к объектам. Вы должны блокировать объект везде, где у вас есть к нему доступ, а не только при его повторении.

Объявление коллекции как изменчивой не будет иметь никакого положительного эффекта. Это приводит только к барьеру памяти перед чтением и после записи ссылки на коллекцию. Он не синхронизирует чтение или запись коллекции.

Ваш ответ на вопрос