Защита от условий гонки в 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);
}
}