Middle
193
questionbank
Как можно отменить выполнение задачи (task) в C#?
Answer from AI
sobes.tech AI
Для отмены выполнения задачи в C# используется механизм CancellationToken и CancellationTokenSource.
- Создается
CancellationTokenSource. - Из
CancellationTokenSourceполучаетсяCancellationToken. CancellationTokenпередается в метод, который выполняет задачу.- Внутри выполняемого метода периодически проверяется свойство
IsCancellationRequestedтокена. - Если
IsCancellationRequestedравноtrue, генерируетсяOperationCanceledExceptionили выполняется другая логика завершения работы. - Для запроса отмены вызывается метод
Cancel()у объектаCancellationTokenSource.
Пример использования:
using System;
using System.Threading;
using System.Threading.Tasks;
// Создаем источник токенов отмены
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
// Создаем задачу
Task task = Task.Run(() =>
{
try
{
for (int i = 0; i < 100; i++)
{
// Проверяем, запрошена ли отмена
if (token.IsCancellationRequested)
{
// Генерируем исключение OperationCanceledException
token.ThrowIfCancellationRequested();
}
// Имитация работы
Console.WriteLine($"Работаю... {i}");
Thread.Sleep(100);
}
}
catch (OperationCanceledException)
{
// Обработка исключения отмены
Console.WriteLine("Задача отменена.");
}
catch (Exception ex)
{
// Обработка других исключений
Console.WriteLine($"Произошла ошибка: {ex.Message}");
}
}, token); // Передаем токен в задачу
// Ждем некоторое время, затем запрашиваем отмену
Thread.Sleep(500);
Console.WriteLine("Запрашиваю отмену...");
cts.Cancel();
// Ждем завершения задачи
try
{
task.Wait();
}
catch (AggregateException ae)
{
// Обработка исключений, включая OperationCanceledException
foreach (var e in ae.InnerExceptions)
{
if (e is OperationCanceledException)
{
Console.WriteLine("Завершена отмененная задача (через Wait).");
}
else
{
// Обработка других исключений
Console.WriteLine($"Ошибка при завершении задачи: {e.Message}");
}
}
}
Console.WriteLine("Основная программа завершена.");
Альтернативы:
- Возврат специального значения или флага из задачи.
- Проверка флага, установленного извне, без использования
CancellationToken.
Однако, CancellationToken является стандартным и рекомендуемым подходом благодаря своей интеграции с Task Parallel Library (TPL), асинхронными операциями и поддержке OperationCanceledException.