TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.77K subscribers
Post #1934 1.53K
День 1588. #ЗаметкиНаПолях
Полезные Расширения для Task<T>
Сегодня рассмотрим 5 полезных методов расширения для Task.

1. Запустил и забыл
Иногда нужно начать задачу и не ждать её завершения. Например, для некритических задач, когда не важен результат. Создадим метод расширения FireAndForget. При желании можно передать методу обработчик ошибок, который будет вызываться, когда задача выдаёт исключение:
public static void FireAndForget(
this Task task,
Action<Exception> errorHandler = null)
{
task.ContinueWith(t =>
{
if (t.IsFaulted && errorHandler != null)
errorHandler(t.Exception);
},
TaskContinuationOptions.OnlyOnFaulted);
}

Использование:
SendEmailAsync().FireAndForget(
e => Console.WriteLine(e.Message));

2. Повтор
Чтобы повторять задачу определённое количество раз, создадим метод расширения Retry. Он будет повторять задачу до тех пор, пока она не завершится успешно или не будет достигнуто максимальное количество попыток. Можно передать задержку между попытками:
public static async Task<TResult> 
Retry<TResult>(
this Func<Task<TResult>> taskFactory,
int maxRetries,
TimeSpan delay)
{
for (int i = 0; i < maxRetries; i++)
{
try
{
return await taskFactory()
.ConfigureAwait(false);
}
catch
{
if (i == maxRetries - 1)
throw;
await Task.Delay(delay)
.ConfigureAwait(false);
}
}
// не должно достигать этого места
return default(TResult);
}

Использование:
var result = await (
() => GetResultAsync())
.Retry(3, TimeSpan.FromSeconds(1));

3. Действие при сбое
Выполняется при возникновении исключения в задаче:
public static async Task 
OnFailure(this Task task,
Action<Exception> onFailure)
{
try
{
await task.ConfigureAwait(false);
}
catch (Exception ex)
{
onFailure(ex);
}
}

Использование:
await GetResultAsync()
.OnFailure(ex => Console.WriteLine(ex.Message));

4. Тайм-аут
Установка тайм-аута для задачи полезна, когда вы хотите, чтобы задача не выполнялась слишком долго (подойдёт, если задача не принимает токена отмены):
public static async Task 
WithTimeout(this Task task,
TimeSpan timeout)
{
var delayTask = Task.Delay(timeout);
var completedTask = await
Task.WhenAny(task, delayTask)
.ConfigureAwait(false);
if (completedTask == delayTask)
throw new TimeoutException();

await task;
}

Использование:
await GetResultAsync()
.WithTimeout(TimeSpan.FromSeconds(1));

Замечание: Начиная с .NET 6 для этой цели можно использовать WaitAsync.

5. Результат по умолчанию
Иногда нужно вернуть результат по умолчанию при сбое задачи:
public static async Task<TResult> 
Fallback<TResult>(
this Task<TResult> task,
TResult fallbackValue)
{
try
{
return await task.ConfigureAwait(false);
}
catch
{
return fallbackValue;
}
}

Использование:
var result = await GetResultAsync()
.Fallback("fallback");

Источник: https://steven-giesel.com/blogPost/d38e70b4-6f36-41ff-8011-b0b0d1f54f6e
  • 👍 26
More from @netdeveloperdiary
  1. Oct 10, 2026День 2810. #ЧтоНовенького #VSCode Более Быстрый и Лёгкий C# Dev Kit Мы, разработчики, люби…
  2. Oct 9, 2026День 2809. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Окончание Начало 3.…
  3. Oct 8, 2026День 2808. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Начало В ИТ есть се…
  4. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
  5. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  6. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →