Что такое Task в C#?

«Что такое Task в C#?» — вопрос из категории C# Core, который задают на 54% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Ключевые характеристики:

  • Task: Представляет операцию без возвращаемого значения.
  • Task<TResult>: Представляет операцию, возвращающую результат типа TResult.
  • Состояния: Задача может находиться в состояниях Running, WaitingToRun, RanToCompletion, Faulted (с ошибкой) или Canceled.
  • Управление ресурсами: Task использует пул потоков (ThreadPool), что эффективнее прямого создания потоков (Thread).

Практическое использование:

// 1. Создание и запуск задачи, возвращающей результат
Task<int> longRunningTask = Task.Run(() =>
{
    Thread.Sleep(1000); // Имитация долгого вычисления
    return 42;
});

// 2. Ожидание завершения задачи и получение результата (блокирует поток)
int result = longRunningTask.Result; // Не рекомендуется в UI-потоке!

// 3. Асинхронное ожидание с помощью await (не блокирует поток)
async Task ProcessDataAsync()
{
    int asyncResult = await longRunningTask;
    Console.WriteLine($"Результат: {asyncResult}");
}

// 4. Задача с отменой
var cancellationTokenSource = new CancellationTokenSource();
Task taskWithCancel = Task.Run(() =>
{
    while (true)
    {
        cancellationTokenSource.Token.ThrowIfCancellationRequested();
        // Работа...
    }
}, cancellationTokenSource.Token);

cancellationTokenSource.CancelAfter(2000); // Отменить через 2 сек.

Отличие от Thread:

  • Thread — низкоуровневая абстракция операционной системы. Создание нового потока — дорогая операция.
  • Task — высокоуровневая абстракция над работой, которая планируется на потоки из пула. Это более эффективно с точки зрения ресурсов. Задача не обязательно выполняется на отдельном потоке (например, при await на уже завершенной операции).