Встречается на 34% собеседований по C#

Что такое Task

Task в C# представляет асинхронную операцию, которая может выполняться параллельно или в фоне. Это часть Task Parallel Library (TPL) и основа механизма async/await. Task позволяет запускать длительные или ресурсоемкие операции, не блокируя основной поток, и получать результат по завершении.

Как это работает

Task использует пул потоков (ThreadPool) для выполнения работы. Когда вы создаете Task, он планируется на одном из потоков пула, что эффективнее, чем создание нового потока вручную. Основные возможности Task:

  • Асинхронное ожидание: оператор await приостанавливает выполнение метода до завершения Task, не блокируя поток.
  • Возврат результата: Task<T> позволяет получить результат асинхронной операции.
  • Отмена: с помощью CancellationToken можно отменить выполнение Task.
  • Композиция: Task можно комбинировать с помощью Task.WhenAll, Task.WhenAny и других методов.

Пример

csharp
async Task<int> GetDataAsync()
{
    await Task.Delay(1000); // Имитация долгой операции
    return 42;
}

// Использование
var result = await GetDataAsync();
Console.WriteLine(result); // 42

В этом примере GetDataAsync возвращает Task<int>, который завершится через 1 секунду и вернет 42. Оператор await позволяет получить результат без блокировки вызывающего потока.

Отличие от Thread

Основное отличие Task от Thread в том, что Task использует пул потоков, что снижает накладные расходы на создание и управление потоками. Thread создает новый поток для каждой операции, что может быть затратно. Task также предоставляет более высокоуровневый API для работы с асинхронностью, включая поддержку отмены и возврата результатов.

Подводные камни

  • Не блокируйте поток: избегайте вызова .Result или .Wait() в синхронном контексте, так как это может привести к взаимоблокировкам.
  • Исключения: исключения, возникшие в Task, сохраняются и выбрасываются при ожидании через await или .Result.
  • Контекст синхронизации: в UI-приложениях await возвращает выполнение в исходный контекст, что может вызвать проблемы, если не использовать ConfigureAwait(false).

Когда использовать

Task следует использовать для асинхронных операций, таких как ввод-вывод, сетевые запросы, работа с файлами и базами данных. Он также полезен для параллельного выполнения независимых задач. Вместо ручного создания Thread предпочтительнее использовать Task, так как это проще и эффективнее.

Коротко

  • Task — это абстракция асинхронной операции, основанная на пуле потоков.
  • Используйте await для ожидания Task без блокировки потока.
  • Task<T> возвращает результат, а CancellationToken позволяет отменить выполнение.
  • Task эффективнее Thread и является основой async/await в C#.
как отвечать на вопрос
пример собеседования
фреймворки на собеседовании
типичные вопросы junior
интервью вопросы и ответы