V3223. Inconsistent use of a potentially shared variable with and without a lock can lead to a data race.
Анализатор обнаружил ситуацию, в которой общий ресурс используется без блокировки, однако в другом месте этот ресурс используется с блокировкой.
Рассмотрим пример:
public class UserSessionManager
{
private static int _activeSessionCount = 0;
private static readonly object _lock = new object();
public void StartSession()
{
lock (_lock)
{
_activeSessionCount++;
....
}
}
public void EndSession()
{
_activeSessionCount--;
....
}
....
}
Класс UserSessionManager
управляет числом активных сессий. Метод StartSession
корректно инкрементирует счётчик с использованием lock
, однако метод EndSession
декрементирует тот же счётчик без блокировки. Это нарушает согласованность доступа к общему ресурсу _activeSessionCount
.
Отсутствие блокировки может привести к состоянию гонки при одновременной работе нескольких потоков.
Для корректной работы в метод EndSession
нужно добавить lock
:
public class UserSessionManager
{
private static int _activeSessionCount = 0;
private static readonly object _lock = new object();
public void StartSession()
{
lock (_lock)
{
_activeSessionCount++;
....
}
}
public void EndSession()
{
lock (_lock)
{
_activeSessionCount--;
....
}
}
....
}
Выявляемые диагностикой ошибки классифицируются согласно ГОСТ Р 71207–2024 как критические и относятся к типу: Ошибки при работе с многопоточными примитивами (интерфейсами запуска потоков на выполнение, синхронизации и обмена данными между потоками и пр.). |
Данная диагностика классифицируется как: