`Cancel()` метод объекта `CancellationTokenSource` не отменяет выполнение объекта `Task` напрямую. Этот метод устанавливает состояние токена отмены, связанного с `CancellationTokenSource`, в отмененное. Однако, чтобы отмена действительно повлияла на выполнение задачи (`Task`), задача должна периодически проверять состояние этого токена, и если токен находится в состоянии отмены, должен произойти выброс исключения `OperationCanceledException`.
Если задача не проверяет токен отмены, то вызов `Cancel()` не остановит её выполнение. Вот простой пример кода, который демонстрирует это поведение:
```csharp
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main()
{
// Создание токена отмены
var cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token;
// Запускаем задачу, которая проверяет токен отмены
Task task = Task.Run(() =>
{
for (int i = 0; i < 5; i++)
{
if (cancellationToken.IsCancellationRequested)
{
Console.WriteLine("Task отменен");
// Если задача не выбрасывает исключение, она завершится корректно,
// но будет иметь статус RanToCompletion вместо Canceled.
cancellationToken.ThrowIfCancellationRequested();
}
// Имитируем длительную работу
Thread.Sleep(1000);
Console.WriteLine($"Итерация {i}");
}
}, cancellationToken); // Передача токена отмены не обязательна для использования внутри задачи
// Отменяем задачу спустя 3 секунды
Task.Run(() =>
{
Thread.Sleep(3000);
Console.WriteLine("Запрос на отмену задачи");
cancellationTokenSource.Cancel();
});
try
{
task.Wait(); // Ожидаем завершения работы task
}
catch (AggregateException ae)
{
if (ae.InnerExceptions[0] is TaskCanceledException)
{
Console.WriteLine("Задача была отменена через исключение TaskCanceledException");
}
}
finally
{
cancellationTokenSource.Dispose();
}
Console.WriteLine($"Задача завершена со статусом: {task.Status}");
}
}
```
В этом примере задача проверяет, была ли запросена отмена через токен отмены. Если отмена была запрошена, выполняется вызов `cancellationToken.ThrowIfCancellationRequested()`, который генерирует исключение `OperationCanceledException`, и задача завершает своё выполнение. Также есть код, который извне через определенное время запрашивает отмену задачи с помощью `Cancel()`.
Очень важно, чтобы задача проверяла состояние токена отмены и корректно реагировала на запрос отмены, иначе задача просто будет выполнена до конца.