Sobes.tech
Middle

Kaip atšaukti užduoties (task) vykdymą C#?

sobes.tech AI

Atsakymas iš AI

Užduoties atšaukimui C# naudojamas CancellationToken ir CancellationTokenSource mechanizmas.

  1. Sukuriamas CancellationTokenSource.
  2. CancellationTokenSource gaunamas CancellationToken.
  3. CancellationToken perduodamas į metodą, kuris vykdo užduotį.
  4. Viduje vykdomo metodo periodiškai tikrinama IsCancellationRequested savybė.
  5. Jei IsCancellationRequested yra true, generuojama OperationCanceledException arba atliekama kita užbaigimo logika.
  6. Norint prašyti atšaukimo, iškviečiama Cancel() metodo CancellationTokenSource objekte.

Pavyzdys:

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

// Sukuriamas atšaukimo tokenų šaltinis
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;

// Sukuriama užduotis
Task task = Task.Run(() =>
{
    try
    {
        for (int i = 0; i < 100; i++)
        {
            // Patikrinama, ar prašoma atšaukimo
            if (token.IsCancellationRequested)
            {
                // Generuojama `OperationCanceledException`
                token.ThrowIfCancellationRequested();
            }

            // Imituojamas darbas
            Console.WriteLine($"Dirbu... {i}");
            Thread.Sleep(100);
        }
    }
    catch (OperationCanceledException)
    {
        // Atšaukimo išimties apdorojimas
        Console.WriteLine("Užduotis atšaukta.");
    }
    catch (Exception ex)
    {
        // Kitų išimčių apdorojimas
        Console.WriteLine($"Klaida: {ex.Message}");
    }
}, token); // Perduodame tokeną užduočiai

// Laukiame tam tikrą laiką, tada prašome atšaukimo
Thread.Sleep(500);
Console.WriteLine("Prašau atšaukimo...");
cts.Cancel();

// Laukiame užduoties pabaigos
try
{
    task.Wait();
}
catch (AggregateException ae)
{
    // Apdorojame išimtis, įskaitant `OperationCanceledException`
    foreach (var e in ae.InnerExceptions)
    {
        if (e is OperationCanceledException)
        {
            Console.WriteLine("Atšaukta užduotis baigta (per Wait).");
        }
        else
        {
            // Kitų išimčių apdorojimas
            Console.WriteLine($"Klaida užbaigiant užduotį: {e.Message}");
        }
    }
}

Console.WriteLine("Pagrindinė programa baigta.");

Alternatyvos:

  • Grąžinti specialią reikšmę arba žymeklį iš užduoties.
  • Patikrinti išorėje nustatytą žymeklį be CancellationToken.

Tačiau CancellationToken yra standartinis ir rekomenduojamas požiūris dėl savo integracijos su Task Parallel Library (TPL), asinchroninėmis operacijomis ir OperationCanceledException palaikymo.