dotnetdad .NET бэкенд

Многопоточность в C#

От потока в операционной системе до сервиса под нагрузкой

7 000 ₽14 000 ₽Предзаказ скоро откроется

Предзаказ. Уроки выходят по мере записи и открываются без доплаты. Эта цена действует, пока идёт предзаказ. После — 14 000 ₽.

Первый раздел — 3 урока — будет открыт всем, как только выйдет: по нему видно, как устроены остальные.

Многопоточность спрашивают на четырёх собеседованиях .NET-бэкендера из пяти.

У каждого раздела ниже — как часто звучат его вопросы и сколько на них заваливают.

Один вопрос до дна

Зачёркнут ответ, после которого интервьюер кивает и идёт дальше. Рядом — тот же вопрос по четырём слоям.

Как работает async/await?
Метод уходит в фоновый поток и не блокирует основной
  1. Механика Компилятор режет метод по await и собирает из кусков машину состояний. На незавершённом await остаток метода подписывается продолжением на ожидаемую задачу, а вызывающему уходит незавершённый Task.
  2. Почему так Пока база отвечает, поток не ждёт: он вернулся в пул и обслуживает другие запросы. Отдельного потока на ожидание нет.
  3. Как ломается Стоит где-то в цепочке появиться .Result — и поток снова ждёт базу. Этот код выполняется в каждом запросе, и под нагрузкой так встают все потоки пула.
  4. Как увидеть В дампе все потоки пула стоят в одном месте — в ожидании задачи. Очередь пула растёт, процессор свободен.

Для кого

Для .NET бэкенд-разработчика, которому важно не натаскаться, а разобраться. Вход — джун и мидл, выход — сеньор и выше.

Начинаем с потоков и операционной системы, а не с async. Самый частый вопрос — как работает async/await — чаще всего заваливают те, кто отвечает про потоки, не понимая, что такое пул и что такое Task. Поэтому async здесь седьмой раздел, а не первый.

Примеры только серверные: ASP.NET Core, очереди, сервис под нагрузкой. Unity, WPF и UI-поток не разбираем — там те же слова значат другое.

Как устроен

Лестница снизу вверх: поток → гонка → блокировка → пул → Task → async → отмена → аллокации → сервис под нагрузкой. Каждая ступень объясняется через нижнюю: async не понять без пула, пул — без потока.

Скилл выходит в две стадии. Первая версия — 30 уроков и четыре стенда: задания в открытом репозитории, где проблему надо воспроизвести и починить. Финал — ещё 23 урока и четыре стенда: модель памяти, внутренности ThreadPool, полная диагностика, параллелизм. Купившим первую версию финал достаётся без доплаты.

Программа

14 разделов, 53 урока. Разделы идут снизу вверх — каждый объясняется через предыдущий. У раздела — его самый частый вопрос из разборов настоящих собеседований.

  1. 1 Карта: поток, параллельность, асинхронность В чём разница между многопоточностью, параллельностью и асинхронностью? вопросы раздела — на ~23% собеседований, заваливают 38%, раздел будет открыт всем 3 урока
    1. 1.1 Процесс, поток и что стоит поток бесплатно, готовится
    2. 1.2 Многопоточность, параллельность, асинхронность — три разных слова бесплатно, готовится
    3. 1.3 CPU-bound и IO-bound бесплатно, готовится
  2. 2 Гонки и атомарность Что такое Interlocked и зачем он нужен? вопросы раздела — на ~12% собеседований, заваливают 20% 2 урока
    1. 2.1 Почему ++ не атомарен готовится
    2. 2.2 Interlocked готовится
  3. 3 Блокировки Чем Mutex отличается от Semaphore и lock? вопросы раздела — на ~23% собеседований, заваливают 30% 3 урока
    1. 3.1 lock изнутри готовится
    2. 3.2 Режим пользователя, режим ядра и почему «Slim» готовится
    3. 3.3 Дедлок готовится
  4. 4 Примитивы синхронизации Какие примитивы синхронизации есть в .NET? вопросы раздела — на ~37% собеседований, заваливают 36% 4 урока
    1. 4.1 SemaphoreSlim готовится
    2. 4.2 Сигналы готовится
    3. 4.3 ReaderWriterLockSlim, SpinLock, SpinWait готовится
    4. 4.4 Карта примитивов: сценарий → инструмент готовится
  5. 5 ThreadPool Как работает пул потоков и как его настраивать? вопросы раздела — на ~8% собеседований 4 урока
    1. 5.1 Зачем пул и из чего он состоит готовится
    2. 5.2 Инжекция потоков и исчерпание готовится
    3. 5.3 Hill climbing и work stealing готовится
    4. 5.4 Как рантайм узнаёт, что база ответила готовится
  6. 6 Task В чём разница между Thread и Task? вопросы раздела — на ~20% собеседований, заваливают 29% 4 урока
    1. 6.1 Task — обещание, а не поток готовится
    2. 6.2 Исключения в Task готовится
    3. 6.3 Комбинаторы готовится
    4. 6.4 TaskCompletionSource, TaskScheduler, Task.Yield готовится
  7. 7 async/await: как это работает Как работает async/await? вопросы раздела — на ~65% собеседований, заваливают 27% 11 уроков
    1. 7.1 async — не про потоки готовится
    2. 7.2 Что происходит на await готовится
    3. 7.3 Машина состояний готовится
    4. 7.4 SynchronizationContext и где его нет готовится
    5. 7.5 ConfigureAwait(false) готовится
    6. 7.6 .Result и .Wait(): дедлок и его мутация готовится
    7. 7.7 async void, забытый await и куда деваются исключения готовится
    8. 7.8 Thread.Sleep против Task.Delay готовится
    9. 7.9 await внутри lock готовится
    10. 7.10 ExecutionContext, AsyncLocal, ThreadLocal готовится
    11. 7.11 Гигиена async готовится
  8. 8 Отмена Зачем нужен CancellationToken и как отменить задачу? вопросы раздела — на ~9% собеседований 2 урока
    1. 8.1 Кооперативная отмена готовится
    2. 8.2 Связывание, таймауты, ASP.NET Core готовится
  9. 9 ValueTask и аллокации Чем ValueTask отличается от Task и когда что брать? вопросы раздела — на ~8% собеседований, заваливают 33% 2 урока
    1. 9.1 Task против ValueTask готовится
    2. 9.2 IValueTaskSource и пул машин состояний готовится
  10. 10 Почему сервис встал Что такое thread starvation? 6 уроков
    1. 10.1 Starvation на стенде готовится
    2. 10.2 Первые метрики готовится
    3. 10.3 Дамп живого процесса готовится
    4. 10.4 Трейсы готовится
    5. 10.5 Дерево диагностики готовится
    6. 10.6 Сервис под нагрузкой: всё вместе готовится
  11. 11 Коллекции и очереди Как устроен ConcurrentDictionary? 4 урока
    1. 11.1 Потокобезопасные коллекции готовится
    2. 11.2 Producer-consumer: BlockingCollection готовится
    3. 11.3 Channel<T> готовится
    4. 11.4 IAsyncEnumerable готовится
  12. 12 Модель памяти и lock-free Что такое volatile и когда он нужен? 4 урока
    1. 12.1 Кэши, переупорядочивание, видимость готовится
    2. 12.2 volatile и барьеры готовится
    3. 12.3 Lock-free и CAS готовится
    4. 12.4 Неизменяемость как стратегия готовится
  13. 13 Параллелизм Сколько потоков используют Parallel.For и Parallel.ForEachAsync? 3 урока
    1. 13.1 Parallel.For, ForEach, ForEachAsync готовится
    2. 13.2 PLINQ готовится
    3. 13.3 TPL Dataflow готовится
  14. 14 Async в тестах 1 урок
    1. 14.1 Как тестировать асинхронный и многопоточный код готовится
7 000 ₽14 000 ₽Предзаказ скоро откроется

Предзаказ. Уроки выходят по мере записи и открываются без доплаты. Эта цена действует, пока идёт предзаказ. После — 14 000 ₽.

  • Доступ на год, продление бесплатное — кнопкой в кабинете. Ссылка для входа приходит на почту, пароль не нужен.
  • Семь дней на возврат без объяснения причин — с того дня, как тебе открылся первый урок. Тоже кнопкой в кабинете, писать никому не надо.