2015-01-30 2 views
0

У меня есть массив, к которому периодически обращаются несколько потоков примерно каждую секунду (один поток писем и один или два считывателя).Использование ConcurrentBag вместо массивов (многопоточность)

После поиска я изначально думал об использовании операторов «Lock» или «Monitor» для защиты критического кода (Насколько я понимаю, критический код в моем случае - тот, который записывает в массив).

Затем я обнаружил, что .Net 4.x представила новый Concurrent Collections, который мне показался, что он мне подходит.

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

Примечание: Мне не нужна сортировка, динамическое изменение размера или любая другая операция в этом массиве \ list. Это будет фиксированная длина и понадобится для чтения и записи

Заранее спасибо.

+0

Невозможно представить, не видя более подробных сведений о том, что вы делаете. Вам также необходимо синхронизировать чтения, если вы одновременно записываете одни и те же данные. – usr

ответ

1

Обычно я бы хотел использовать «доступные доступные параллельные классы», потому что они хорошо разработаны и тщательно протестированы и лучше подходят для большинства случаев использования, чем любые самодельные многопоточные решения.

Но поскольку вы просите простое решение без необходимости динамического изменения размера, просто перейдите к оператору lock (который, кстати, использует класс Monitor за кулисами).

Будьте осторожны, так как это

Как я понимаю, критический код в моем случае это тот, который записывает в массив.

не соответствует действительности. Критический код в вашем случае и в большинстве других случаев - это любой код, который обращается к общим ресурсам, будь то чтение или запись.

Лучшая практика, вероятно, будет что-то вроде этого:

private object syncLock = new object(); 
private string[] yourArray = whatever; 

private void ThisMethodReads() 
{ 
    ... 
    lock (this.syncLock) 
    { 
     // Read from the array. 
    } 
    ... 
} 

private void ThisMethodReadsAndWrites() 
{ 
    ... 
    lock (this.syncLock) 
    { 
     // Read from and/or write to the array. 
    } 
    ... 
} 

Чтобы получить лучшее понимание проблем многопоточности и пути их решения, я обычно рекомендую Joe Albahari's multithreading tutorial.

+0

Большое спасибо за ваш ответ. Причина, по которой я пытаюсь использовать один из «легко доступных параллельных классов» вместо оператора «Заблокировать», заключается в том, чтобы исключить любые проблемы с потоком, такие как блокировки. –

+0

Кроме того, я понимаю, что «readwriterlockslim» может использоваться только для записывающей части и устраняет необходимость «блокировки» кода чтения. Я прав? –

+0

Теоретически, да. На практике вы сказали, что будете вызывать код один раз в секунду или около того. В зависимости от того, сколько времени ваш код выполняет, вам просто не нужно. Используйте ReaderWriterLockSlim, только если у вас много (действительно много) параллельных чтений и только некоторые спорадические записи. Google для сравнения производительности. – Frank

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