Sobes.tech
Middle

Jak anulować wykonanie zadania (task) w C#?

sobes.tech AI

Odpowiedź od AI

Aby anulować wykonywanie zadania w C#, używa się mechanizmu CancellationToken i CancellationTokenSource.

  1. Tworzy się CancellationTokenSource.
  2. Z CancellationTokenSource pobiera się CancellationToken.
  3. CancellationToken jest przekazywany do metody wykonującej zadanie.
  4. Wewnątrz wykonywanej metody okresowo sprawdzana jest właściwość IsCancellationRequested tokenu.
  5. Jeśli IsCancellationRequested jest true, generowany jest OperationCanceledException lub wykonywana inna logika zakończenia.
  6. Aby zażądać anulowania, wywołuje się metodę Cancel() na obiekcie CancellationTokenSource.

Przykład użycia:

using System;
using System.Threading;
using System.Threading.Tasks;

// Tworzymy źródło tokenów anulowania
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;

// Tworzymy zadanie
Task task = Task.Run(() =>
{
    try
    {
        for (int i = 0; i < 100; i++)
        {
            // Sprawdzamy, czy zażądano anulowania
            if (token.IsCancellationRequested)
            {
                // Generujemy OperationCanceledException
                token.ThrowIfCancellationRequested();
            }

            // Symulacja pracy
            Console.WriteLine($"Pracuję... {i}");
            Thread.Sleep(100);
        }
    }
    catch (OperationCanceledException)
    {
        // Obsługa wyjątku anulowania
        Console.WriteLine("Zadanie anulowane.");
    }
    catch (Exception ex)
    {
        // Obsługa innych wyjątków
        Console.WriteLine($"Wystąpił błąd: {ex.Message}");
    }
}, token); // Przekazujemy token do zadania

// Czekamy trochę, a następnie żądamy anulowania
Thread.Sleep(500);
Console.WriteLine("Żądanie anulowania...");
cts.Cancel();

// Czekamy na zakończenie zadania
try
{
    task.Wait();
}
catch (AggregateException ae)
{
    // Obsługa wyjątków, w tym OperationCanceledException
    foreach (var e in ae.InnerExceptions)
    {
        if (e is OperationCanceledException)
        {
            Console.WriteLine("Zadanie anulowane (przez Wait)." );
        }
        else
        {
            // Obsługa innych wyjątków
            Console.WriteLine($"Błąd podczas kończenia zadania: {e.Message}");
        }
    }
}

Console.WriteLine("Główny program zakończył działanie.");

Alternatywy:

  • Zwracanie specjalnej wartości lub flagi z zadania.
  • Sprawdzanie flagi ustawionej z zewnątrz, bez użycia CancellationToken.

Jednak CancellationToken jest standardowym i zalecanym podejściem ze względu na jego integrację z Task Parallel Library (TPL), operacjami asynchronicznymi i obsługą OperationCanceledException.