Защита от условий гонки в System.Collections.Concurrent.ConcurrentDictionary

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

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

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

1 ответ

Решение

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

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

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

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

lock(locker)
{
   if(!collection.Check(value)) 
   {
       collection.Add(value);
   }
}
Другие вопросы по тегам