Коротко по сути:
lock не работает в `async`-методах. Причина проста — выполнение может продолжиться на другом потоке, и гарантии взаимного исключения теряются.
Что использовать вместо `lock` в асинхронном коде:
-
SemaphoreSlim — основной вариант -
Semaphore -
Mutex -
Monitor (в синхронных сценариях)Правильный шаблон:
1. Всегда используйте таймаут, чтобы избежать зависаний.
2. Освобождайте ресурс в `finally`, иначе возможна утечка блокировки.
Примерный подход:
- попытаться войти с ограничением времени
- выполнить критическую секцию
- гарантированно освободить семафор
Почему это важно:
В многопоточном и распределённом окружении неправильная синхронизация приводит к гонкам, дублированию запросов, «штормам» в кеше и нагрузке на внешний API.
Вопрос для практики:
Как реализовать блокировку на уровне базы данных, чтобы синхронизировать несколько инстансов приложения?
Ответ — в разборе по distributed locking:
milanjovanovic.tech/blog/distributed-locking-in-dotnet-coordinating-work-across-multiple-instances
