lock обеспечивает взаимное исключение, для простого счётчика подходит Interlocked.Increment. Await внутри lock запрещён; для асинхронного ожидания обычно используют SemaphoreSlim.WaitAsync.
Что такое `lock`, как сделать инкремент атомарным, почему `lock` нельзя сочетать с `await`, чем `SemaphoreSlim` отличается от `Semaphore` и что будет при использовании value type как объекта синхронизации?
lock обеспечивает взаимное исключение, для простого счётчика подходит Interlocked.Increment. Await внутри lock запрещён; для асинхронного ожидания обычно используют SemaphoreSlim.WaitAsync.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
lock обеспечивает взаимное исключение, для простого счётчика подходит Interlocked.Increment. Await внутри lock запрещён; для асинхронного ожидания обычно используют SemaphoreSlim.WaitAsync.
Для обычного reference-object lock основан на Monitor и привязан к потоку, а async-продолжение может сменить поток. C# также запрещает await в теле lock на уровне языка. В новых версиях есть специальная поддержка System.Threading.Lock, но это не делает await внутри допустимым.
SemaphoreSlim работает внутри процесса и поддерживает неблокирующее ожидание; системный Semaphore может быть именованным и межпроцессным. Прямой lock по int не компилируется. При отдельном boxing одного значения в разные object получаются разные объекты блокировки, поэтому синхронизации между ними не будет. Используйте отдельный стабильный объект, не строки и не publicly доступный this.
Источник: learn.microsoft.com.