0Pricing
C# Academy · Урок

ConfigureAwait и распространение исключений

Разберитесь в захвате контекста и ConfigureAwait(false); обрабатывайте исключения с await и при блокирующих вызовах; изучите AggregateException и лучшие практики.

«ConfigureAwait и распространение исключений» — бесплатный урок C# Academy на CoddyKit. Это урок 3 из 3. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 3 уроков всего.

Контекст и исключения

Цели:

  • Понять, что такое захват контекста
  • Знать, когда использовать ConfigureAwait(false)
  • Понять, как распространяются исключения при использовании await
  • Понять, почему blocking приводит к AggregateException

Рекомендация для библиотек

Методы библиотек должны использовать ConfigureAwait(false), чтобы не возобновлять выполнение в контексте пользовательского интерфейса или веб-приложения, которым они не управляют.

using System;
using System.Threading.Tasks;

public static class NetLib
{
  // Library code should not assume a UI context. Use ConfigureAwait(false).
  public static async Task<string> FetchAsync()
  {
    await Task.Delay(100).ConfigureAwait(false); // do not capture context
    return "payload";
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    // Console apps typically have no SynchronizationContext; this still runs fine.
    string s = NetLib.FetchAsync().GetAwaiter().GetResult();
    Console.WriteLine("Got: " + s);
  }
}

Правила работы с контекстом

Захват контекста:

  • По умолчанию await пытается возобновить выполнение в захваченном контексте (пользовательский интерфейс или ASP.NET)
  • ConfigureAwait(false) означает: не захватывать контекст, а продолжить выполнение в пуле потоков
  • Это помогает избежать взаимных блокировок, когда вызывающий код блокирует поток контекста
  • Коду пользовательского интерфейса может понадобиться контекст для обновления элементов управления; библиотечному коду он обычно не нужен

Await и исключения

При использовании await исключение распространяется в виде исходного типа исключения; перехватывайте его обычным способом.

using System;
using System.Threading.Tasks;

public class Program
{
  static async Task<string> BoomAsync()
  {
    await Task.Delay(50);
    throw new InvalidOperationException("boom");
  }

  public static void Main(string[] args)
  {
    // With await (inside async), exceptions rethrow as the original type.
    try
    {
      string r = BoomAsync().GetAwaiter().GetResult(); // emulate await in Main
      Console.WriteLine(r);
    }
    catch (InvalidOperationException ex)
    {
      Console.WriteLine("Caught: " + ex.GetType().Name + " - " + ex.Message);
    }
  }
}

Блокировка и ошибки

Блокировка с помощью .Result или .Wait() оборачивает ошибки в AggregateException; для более понятного распространения ошибок отдавайте предпочтение await.

using System;
using System.Threading.Tasks;

public class Program
{
  static async Task<int> FailsAsync()
  {
    await Task.Delay(30);
    throw new ArgumentException("bad arg");
  }

  public static void Main(string[] args)
  {
    try
    {
      // Blocking with .Result wraps the exception into AggregateException
      int x = FailsAsync().Result;
      Console.WriteLine(x);
    }
    catch (AggregateException ae)
    {
      Exception inner = ae.InnerException;
      Console.WriteLine("AggregateException -> " + (inner == null ? "null" : inner.GetType().Name));
    }
  }
}

Рекомендации

Рекомендации:

  • В библиотеках используйте ConfigureAwait(false)
  • В приложениях с пользовательским интерфейсом и веб-приложениях используйте await в вызывающем потоке, когда нужен контекст
  • Избегайте .Result/.Wait(); перехватывайте исходные исключения с помощью await
  • При необходимости ведите журнал и повторно выбрасывайте исключения с понятными сообщениями, учитывающими контекст

Поведение ConfigureAwait

Быстрая проверка: что сообщает ConfigureAwait(false) оператору await?

Повторение

Повторение: используйте ConfigureAwait(false) в библиотеках; код пользовательского интерфейса и веб-код сами решают, когда им нужен контекст. Отдавайте предпочтение await для понятного распространения исключений; блокировка оборачивает ошибки и создаёт риск взаимных блокировок.

Часто задаваемые вопросы

Урок «ConfigureAwait и распространение исключений» бесплатный?

Да — полный текст урока «ConfigureAwait и распространение исключений» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 3 уроков всего.

Чему я научусь в уроке «ConfigureAwait и распространение исключений»?

Разберитесь в захвате контекста и ConfigureAwait(false); обрабатывайте исключения с await и при блокирующих вызовах; изучите AggregateException и лучшие практики. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C# Academy?

Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 3.

Сколько времени занимает урок «ConfigureAwait и распространение исключений»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C# Academy?

Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Task/ValueTask и асинхронная машина состояний (концепции)
  2. Подводные камни асинхронности: синхронный вызов асинхронного кода и взаимные блокировки
  3. ConfigureAwait и распространение исключений
← Назад к C# Academy