В каких случаях возвращать void, а в каких Task в C#?

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

Ответ

Выбор между void и Task определяется необходимостью асинхронности и ожидания.

Используйте void для:

  • Синхронных методов, которые не выполняют операций ввода-вывода (I/O) или длительных вычислений.
  • Обработчиков событий (event handlers), так как их сигнатура определена делегатом и не поддерживает await. Исключения здесь должны обрабатываться внутри метода.

Используйте Task (или Task<T>) для:

  • Асинхронных методов, даже если они не возвращают результат (Task). Это позволяет вызывающей стороне:
    • Ожидать завершения операции с помощью await.
    • Правильно обрабатывать исключения, которые "всплывают" из метода.
    • Композировать асинхронные операции (например, с Task.WhenAll).
    • Контролировать состояние задачи (отмена через CancellationToken).

Примеры:

// void – синхронный обработчик события
public void OnButtonClicked(object sender, EventArgs e)
{
    // Синхронная работа
    Log("Button clicked");
}

// Task – асинхронная операция без возвращаемого значения
public async Task ProcessDataAsync(CancellationToken cancellationToken)
{
    await Task.Delay(1000, cancellationToken); // Асинхронное ожидание
    await _fileService.SaveAsync("data.json", cancellationToken); // Асинхронный I/O
    Console.WriteLine("Data processed");
}

Ключевое правило: Преимущественно используйте Task для всех операций, связанных с I/O, сетью или длительными вычислениями. void оставьте для синхронных обработчиков событий.