Асинхронные методы позволяют освобождать текущий поток во время выполнения операций ввода-вывода (I/O) или длительных вычислений, не блокируя его.
public async Task<string> GetDataAsync()
{
// 1. Метод начинает выполнение в вызывающем потоке
var data = await httpClient.GetStringAsync("https://api.example.com/data");
// 3. Продолжение выполняется после завершения операции
return data.ToUpper();
}
Вызов метода:
await
Ожидание операции:
await
поток освобождается (если операция не завершена)Продолжение (continuation):
Компилятор преобразует асинхронный метод в сложную структуру:
// Примерное представление сгенерированного кода
[AsyncStateMachine(typeof(GetDataAsyncStateMachine))]
public Task<string> GetDataAsync()
{
var stateMachine = new GetDataAsyncStateMachine();
stateMachine._this = this;
stateMachine._builder = AsyncTaskMethodBuilder<string>.Create();
stateMachine._state = -1;
stateMachine._builder.Start(ref stateMachine);
return stateMachine._builder.Task;
}
Характеристики:
async
/await
, Task
, ValueTask
Пример:
public async Task ProcessDataAsync()
{
var data1 = await LoadData1Async(); // Освобождает поток во время загрузки
var data2 = await LoadData2Async(); // Освобождает поток во время загрузки
// ...
}
Характеристики:
Parallel.For
, Task.Run
, PLINQ
Пример:
public void ProcessDataInParallel()
{
Parallel.For(0, 100, i =>
{
Compute(i); // Выполняется одновременно в нескольких потоках
});
}
Аспект | Асинхронность | Параллелизм |
---|---|---|
Цель | Эффективность использования потоков | Увеличение производительности |
Потоки | Может использовать 1 поток | Требует несколько потоков |
Блокировка | Не блокирует потоки | Может блокировать потоки |
Идеально для | I/O операций | CPU-bound операций |
Ресурсы | Экономит потоки | Потребляет дополнительные потоки |
public async Task<string> DownloadPageAsync(string url)
{
using var client = new HttpClient();
return await client.GetStringAsync(url);
}
public void ProcessImages(Image[] images)
{
Parallel.ForEach(images, image =>
{
image.ApplyFilters();
});
}
public async Task ProcessAllDataAsync()
{
// Асинхронная загрузка данных
var data = await LoadDataAsync();
// Параллельная обработка
await Task.Run(() =>
{
Parallel.ForEach(data, item =>
{
ProcessItem(item);
});
});
// Асинхронное сохранение
await SaveResultsAsync();
}
асинхронность и параллелизм - это разные концепции для разных задач. Асинхронность позволяет эффективно использовать потоки при операциях ожидания, тогда как параллелизм увеличивает производительность за счет одновременного выполнения кода на нескольких ядрах процессора. Грамотное сочетание этих подходов позволяет создавать высокопроизводительные и отзывчивые приложения.