Вопрос по .net-4.0, c#, multithreading, concurrentdictionary, race-condition – Защита от условий гонки в System.Collections.Concurrent.ConcurrentDictionary

3

.NET ConcurrentDictionary подвержен состоянию гонки, которое может вызвать непредвиденные данные, как объясненовнизу этой статьи MSDN.  Я предполагаю, что необходимо учитывать несколько факторов.

Q: Как мне написать код, который не уязвим к тому состоянию гонки, которое может привести к потере данных?

В моем сценарии у меня есть входной поток, который имеет постоянно увеличивающийся индекс (n ++). Я думаю, что я могобнаружить недостающие данные если возникнет состояние гонки, отправьте его повторно. С другой стороны, может быть лучший способ сделать это, о котором я не знаю.

@ gabba - Моя задача - прочитать данные журнала безопасности из разных источников. Каждая запись в журнале имеет постоянно увеличивающийся индекс. Смотрите обновленный вопрос / ссылку для получения дополнительной информации random65537
Ответ зависит от того, что ты будешь делать. Какое у вас задание? gabba
Avoid GetOrAdd () и AddOrUpdate ()? Henk Holterman

Ваш Ответ

1   ответ
6

.net), о которых должны знать люди, а именно:individual операции могут быть потокобезопасными, но последовательности операций не являются атомарными. Под этим я подразумеваю следующее: предположим, такой сценарий, где у меня есть параллельная коллекция сCheck и анAdd операция, как атомная.

Что я хочу сделать, это проверить, существует ли значение, и если нет, добавить его. Так что я могу написать это:

if(!collection.Check(value)) 
{
    collection.Add(value);
}

Хотя обе операции являются атомарными, приведенная выше последовательность не является таковой, поскольку поток может быть прерван между проверкой и добавлением другим потоком, что приводит к противоречивым результатам. Таким образом, вся последовательность должна быть сделана атомарной, обернув ее вlock утверждение например.

lock(locker)
{
   if(!collection.Check(value)) 
   {
       collection.Add(value);
   }
}
@ Gabba спасибо за подсказку о двойной проверке блокировки ... Я узнаю об этом сейчас. En.wikipedia.org / вики / Double-checked_locking random65537
@ makerofthings7: Да, это может быть проблемой производительности в приложениях, которые требуют очень высокой производительности, и могут использоваться альтернативные методы, такие как версия без блокировки или спин-блокировка, поскольку реальный защищенный код довольно мал. Tudor
Я думаю, что лучше использовать блокировку с двойной проверкой. if (! collection.Check (value)) {lock (locker) {if (! collection.Check (value)) {collection.Add (value); }}} gabba
Разве блокировка не повлияла на производительность? (против SpinLock). Было бы лучше, если бы можно было обнаружить пропущенные данные и просто повторно передать их при возникновении потери данных? random65537

Похожие вопросы