2014-09-04 2 views
0

У меня есть коллекция, как показано ниже?Является ли ICollection <>. Добавить() потокобезопасным?

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

Я хотел бы добавить MyClass элементы в Property после загрузки каждого MyClass элемента из БД. Теперь каждый выборка DB обрабатывается отдельными фоновыми потоками, и они запускаются одновременно. Таким образом, каждое возвращаемое значение из вызова БД встречается Property.Add(). Теперь это может привести к условиям гонки, так как Property.Add() можно назвать несколько раз в одно мгновение.

Так что мой вопрос: List<>.Add() или любой другой класс, реализующий ICollection<>.Add(), внутренне обрабатывать любые условия гонки или он должен быть явно обработан? Если да, то как?

+3

'ICollection ' это интерфейс. Конкретная реализация этого интерфейса может быть потокобезопасной, а может и не быть, но на самом деле не имеет смысла говорить о безопасности потоков самого интерфейса. Вопрос должен состоять в том, является ли 'List .Add()' потокобезопасным. – hvd

+1

В классах коллекции в System.Collections.Generic не предусмотрена ни одна синхронизация потоков; код пользователя должен обеспечивать всю синхронизацию при добавлении или удалении элементов одновременно. Если вам нужно обеспечить безопасность потока в пространстве имен 'System.Collections.Concurrent'. http://msdn.microsoft.com/en-us/library/dd997305(v=vs.110).aspx –

+0

Список не является потокобезопасным. Это упоминается в разделе «Безопасность потока» в документации [класс] (http://msdn.microsoft.com/en-us/library/6sh2ey19 (v = vs.110) .aspx). Этот раздел присутствует в документации по ** всем ** .NET-классам –

ответ

8

ICollection не имеет внутренних деталей; это интерфейс. Реализация может быть или не быть потокобезопасной, но интерфейс ничего не гарантирует.

Это может быть полезно посмотреть:

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

+0

Кажется, что OP будет знать о 'ICollection ' является интерфейсом, поэтому OP предоставил пример кода: 'Property = new List (); ' –

+0

@ MatíasFidemraizer возможно, но вопрос (до того, как он был отредактирован) специально спросил, как ICollection обрабатывает условия гонки. – Dave

2

Вам нужно обрабатывать параллелизм в явном виде. Вот почему существует пространство имен called System.Concurrent.Collections.

Если порядок не имеет значения, you might need to take a look to ConcurrentBag<T>. В противном случае, вы должны будете предоставить свою собственную реализацию или производный класс, чтобы обеспечить безопасность потоков любые вышедших из коробки ICollection<T> реализаций, в System.Collections.Generic пространства имен.

1

Ваш конкретный тип List<MyClass>, так что вы должны смотреть на токарно-безопасности List<T>.Add, документированных в List(T) Class:

потокобезопасность

Открытый статический (Общий в Visual Basic) члены этого типа являются потокобезопасными. Любые члены экземпляра не гарантируют безопасность потоков.

Безопасно выполнять несколько операций чтения в списке <T>, но проблемы могут возникать, если коллекция изменяется во время ее чтения. Чтобы обеспечить безопасность потока, заблокируйте сборку во время операции чтения или записи. Чтобы обеспечить доступ к коллекции для нескольких потоков для чтения и записи, вы должны реализовать свою собственную синхронизацию. Для коллекций со встроенной синхронизацией см. Классы в пространстве имен System.Collections.Concurrent. Для альтернативы, не зависящей от потока, см. Класс ImmutableList.

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