Ответ вслух Middle Потоки и синхронизация спрашивают часто обновлено

Синхронизация потоков в .NET

Вопрос

Как вы обеспечиваете потокобезопасность в C#-коде?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Лучшая синхронизация та, которая не нужна. Поэтому сначала стараюсь не разделять изменяемое состояние: неизменяемые объекты и record, данные в локальных переменных, передача сообщений через Channel<T.

Что должно прозвучать в ответе

  • Сначала избегать общего изменяемого состояния: неизменяемые объекты, локальные данные

  • lock для коротких критических секций, на приватном объекте

  • Interlocked для счётчиков и флагов

  • Конкурентные коллекции: ConcurrentDictionary, ConcurrentQueue, Channel

  • SemaphoreSlim для асинхронного кода и ограничения параллелизма

  • Порядок захвата блокировок против дедлоков

Что могут спросить следом

  • Почему нельзя await внутри lock?
  • Чем ConcurrentDictionary лучше Dictionary под lock?
  • Как найти дедлок в проде?

Разбор

Лучшая синхронизация та, которая не нужна. Поэтому сначала стараюсь не разделять изменяемое состояние: неизменяемые объекты и record, данные в локальных переменных, передача сообщений через Channel<T>.

Если общее состояние есть, выбираю инструмент по задаче. Для счётчиков и флагов Interlocked, он без блокировок. Для коротких критических секций lock на приватном readonly-объекте, без вызовов внешнего кода и без await внутри. Для словарей и очередей конкурентные коллекции: ConcurrentDictionary с GetOrAdd и AddOrUpdate.

В асинхронном коде использую SemaphoreSlim с WaitAsync и Release в finally, он же помогает ограничить параллелизм. Чтобы не ловить дедлоки, захватываю несколько блокировок всегда в одном порядке и держу их как можно меньше. Для диагностики в проде снимаю дамп dotnet-dump и смотрю стеки потоков через clrstack и syncblk.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме