2014-09-05 5 views
0

Когда у меня есть этот код:Список <T> (Список <T>) Конструктор потокобезопасный?

public static List<Module> ExtensionList 
{ 
    get 
    { 
     return new List<Module>(Extensions); 
    } 
} 

является его поточно? например. он делает блокировку на Extensions, пока он копирует список? или я должен явно сделать это:

public static List<Module> ExtensionList 
{ 
    get 
    { 
     lock (Extensions) 
     { 
      return new List<Module>(Extensions); 
     } 
    } 
} 
+2

No. Согласно MSDN, все не статические члены в '' Список не guarraned потокобезопасной: «Общественный статический (Shared в Visual Basic) члены этого типа являются потокобезопасными. Любые члены экземпляра не гарантируют безопасность потоков. " Подробнее: http://msdn.microsoft.com/pl-pl/library/6sh2ey19(v=vs.110).aspx – 2014-09-05 07:41:21

+0

@pwas почему это плохая практика? вы можете уточнить? спасибо – Petr

ответ

4

No. MSDN государства ясно, что ни один из методов не List<T> потокобезопасно:

членов экземпляров не гарантируется поточно.

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

Конструктор сам всегда потокобезопасный: вы не можете вызвать его из другого экземпляра еще.

Если вы поставляете свой List<T> конструктор с другим List<T>, как вы делаете в вашем коде, это не безопасно, так как входящий List<T> может измениться во время обработки с помощью конструктора (то применяется вышеуказанное правило).

+0

Я могу это одобрить. Я только что отразил код .NET, и нет оператора блокировки, монитора или чего-то еще. – feO2x

+1

Но это текст котельной, и это вряд ли имеет значение. Очень сложно (невозможно?) Использовать конструктор многопоточный. Вопрос в том, что касается параметра. –

+0

@HenkHolterman: Это в правильном ответе? Я четко заявляю, что если в качестве входящего параметра используется список , он небезопасен. Если вызывается конструктор без параметров, он безопасен. –

1

Даже если вы устанавливаете конструктор в инструкции блокировки, использование списка не будет поточным.

Используйте поточно-коллекцию как BlockingCollection

http://msdn.microsoft.com/en-us/library/dd997305(v=vs.110).aspx

+0

Нет. Нитевидная коллекция упрощает синтаксис - нам не нужно использовать «lock» или любой способ блокировки.Но правильно используемый 'lock' может обеспечить безопасность потоков для любой операции. – 2014-09-05 07:48:16

+0

Axdorph прав в том, что второй образец с 'lock()' не гарантирует безопасность потоков сам по себе. Правильность зависит от другого кода, доступного для расширений. –

+0

@ Ok - справа, внешний класс также должен правильно использовать замок. – 2014-09-05 07:51:09

Смежные вопросы