Асинхронность в C# используется для выполнения операций, не блокируя основной поток выполнения. Это особенно важно при работе с вводом-выводом (I/O), запросами к базе данных и сетевыми вызовами, где задержки могут негативно сказаться на производительности.
Основные принципы асинхронного программирования
C# поддерживает асинхронное программирование с использованием ключевых слов async
и await
, а также типов Task
и Task<T>
. Они позволяют писать код, который выполняется асинхронно без явного управления потоками.
public async Task<string> GetDataAsync()
{
using var httpClient = new HttpClient();
return await httpClient.GetStringAsync("https://example.com");
}
Разница между синхронным и асинхронным кодом
Синхронный код
При выполнении синхронного кода поток блокируется до завершения операции.
public string GetData()
{
using var httpClient = new HttpClient();
return httpClient.GetStringAsync("https://example.com").Result;
}
Этот код заблокирует вызывающий поток, пока не получит ответ от сервера.
Асинхронный код
Асинхронный код позволяет освободить поток, пока выполняется операция.
public async Task<string> GetDataAsync()
{
using var httpClient = new HttpClient();
return await httpClient.GetStringAsync("https://example.com");
}
Здесь выполнение метода приостанавливается на await
, но основной поток может продолжить работу.
Использование async
и await
Ключевое слово async
указывает, что метод выполняется асинхронно, а await
приостанавливает его выполнение до завершения асинхронной операции.
public async Task<int> ProcessDataAsync()
{
await Task.Delay(2000); // Имитация задержки
return 1;
}
Обработка исключений в асинхронном коде
Асинхронные методы могут выбрасывать исключения, которые можно обработать с помощью try-catch
.
public async Task<string> GetDataSafelyAsync()
{
try
{
using var httpClient = new HttpClient();
return await httpClient.GetStringAsync("https://example.com");
}
catch (Exception ex)
{
return $"Ошибка: {ex.Message}";
}
}
Асинхронные коллекции (IAsyncEnumerable<T>
)
Для работы с потоковыми данными в C# можно использовать IAsyncEnumerable<T>
и await foreach
.
public async IAsyncEnumerable<int> GenerateNumbersAsync()
{
for (int i = 0; i < 5; i++)
{
await Task.Delay(1000);
yield return i;
}
}
public async Task ProcessNumbersAsync()
{
await foreach (var number in GenerateNumbersAsync())
{
Console.WriteLine(number);
}
}
Асинхронное программирование в C# позволяет выполнять операции без блокировки потоков, улучшая отзывчивость приложений. Использование async
и await
значительно упрощает работу с асинхронными операциями по сравнению с традиционными подходами на основе потоков.