Подводные камни асинхронности: синхронный вызов асинхронного кода и взаимные блокировки
Научитесь распознавать проблемы асинхронности, например синхронный вызов асинхронного кода и взаимные блокировки. Узнайте, почему блокирующие вызовы могут замораживать приложения и как избегать распространенных ошибок.
«Подводные камни асинхронности: синхронный вызов асинхронного кода и взаимные блокировки» — бесплатный урок C# Academy на CoddyKit. Это урок 2 из 3. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 3 уроков всего.
Обзор подводных камней
Подводные камни: асинхронность упрощает написание кода, но смешивание синхронного и асинхронного выполнения может заморозить приложения или вызвать взаимные блокировки.
Синхронный вызов асинхронного кода
Вызов .Result у Task блокирует поток. В консольных приложениях это может работать, но в контексте пользовательского интерфейса или ASP.NET возникает риск взаимной блокировки.
using System;
using System.Threading.Tasks;
public class Program
{
static async Task<string> SayHelloAsync()
{
await Task.Delay(200); // simulate async delay
return "Hello";
}
public static void Main(string[] args)
{
// BAD: calling .Result blocks the thread
string msg = SayHelloAsync().Result;
Console.WriteLine(msg);
}
}
Более безопасное завершение
В демонстрациях для консоли можно осторожно блокировать поток. В реальных приложениях предпочтителен подход полной асинхронности: помечайте методы как async и используйте await, а не .Result.
using System;
using System.Threading.Tasks;
public class Program
{
static async Task<string> SayHelloAsync()
{
await Task.Delay(200);
return "Hello async";
}
public static void Main(string[] args)
{
// In C# 6, Main is sync; avoid blocking in real apps
string msg = SayHelloAsync().GetAwaiter().GetResult(); // safer than .Result
Console.WriteLine(msg);
}
}
Механизм взаимной блокировки
Цепочка взаимной блокировки:
- Поток блокируется на Task.Result
- Продолжению требуется тот же поток
- Продолжение никогда не выполняется
- Результат не поступает — возникает взаимная блокировка
Проблема Wait()
.Wait() — ещё один блокирующий вызов, который может вызвать те же проблемы, что и .Result.
using System;
using System.Threading.Tasks;
public class Program
{
static async Task<string> WorkAsync()
{
await Task.Delay(100);
return "done";
}
public static void Main(string[] args)
{
// BAD: Wait() can also deadlock in UI/ASP.NET
WorkAsync().Wait();
Console.WriteLine("Completed");
}
}
Рекомендации
Рекомендации:
- Избегайте смешивания синхронного и асинхронного выполнения
- Используйте async/await на всём стеке вызовов
- Блокируйте выполнение только в демонстрационных консольных приложениях
- В приложениях с пользовательским интерфейсом или веб-приложениях никогда не вызывайте .Result или .Wait()
Риск взаимной блокировки при вызове Result
Повторение
Повторение: блокировка асинхронных Task с помощью .Result или .Wait() может привести к взаимным блокировкам. Отдавайте предпочтение async/await на всём стеке вызовов.
Часто задаваемые вопросы
Урок «Подводные камни асинхронности: синхронный вызов асинхронного кода и взаимные блокировки» бесплатный?
Да — полный текст урока «Подводные камни асинхронности: синхронный вызов асинхронного кода и взаимные блокировки» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 3 уроков всего.
Чему я научусь в уроке «Подводные камни асинхронности: синхронный вызов асинхронного кода и взаимные блокировки»?
Научитесь распознавать проблемы асинхронности, например синхронный вызов асинхронного кода и взаимные блокировки. Узнайте, почему блокирующие вызовы могут замораживать приложения и как избегать распр… Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C# Academy?
Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 3.
Сколько времени занимает урок «Подводные камни асинхронности: синхронный вызов асинхронного кода и взаимные блокировки»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C# Academy?
Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Task/ValueTask и асинхронная машина состояний (концепции)
- Подводные камни асинхронности: синхронный вызов асинхронного кода и взаимные блокировки
- ConfigureAwait и распространение исключений