Sobes.tech
Middle

Cum poți anula executarea unei sarcini (task) în C#?

sobes.tech AI

Răspuns de la AI

Pentru a anula executarea unei sarcini în C#, se utilizează mecanismul CancellationToken și CancellationTokenSource.

  1. Se creează un CancellationTokenSource.
  2. Se obține un CancellationToken din CancellationTokenSource.
  3. CancellationToken este transmis către metoda care execută sarcina.
  4. În interiorul metodei în execuție, se verifică periodic proprietatea IsCancellationRequested a tokenului.
  5. Dacă IsCancellationRequested este true, se generează o OperationCanceledException sau se execută o altă logică de finalizare.
  6. Pentru a solicita anularea, se apelează metoda Cancel() pe obiectul CancellationTokenSource.

Exemplu de utilizare:

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

// Crearea unei surse de token-uri de anulare
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;

// Crearea unei sarcini
Task task = Task.Run(() =>
{
    try
    {
        for (int i = 0; i < 100; i++)
        {
            // Verificarea dacă s-a solicitat anularea
            if (token.IsCancellationRequested)
            {
                // Generarea unei excepții OperationCanceledException
                token.ThrowIfCancellationRequested();
            }

            // Simulare de lucru
            Console.WriteLine($"Lucrez... {i}");
            Thread.Sleep(100);
        }
    }
    catch (OperationCanceledException)
    {
        // Tratarea excepției de anulare
        Console.WriteLine("Sarcina a fost anulată.");
    }
    catch (Exception ex)
    {
        // Tratarea altor excepții
        Console.WriteLine($"A apărut o eroare: {ex.Message}");
    }
}, token); // Se transmite token-ul către sarcină

// Se așteaptă un timp și apoi se solicită anularea
Thread.Sleep(500);
Console.WriteLine("Se solicită anularea...");
cts.Cancel();

// Se așteaptă finalizarea sarcinii
try
{
    task.Wait();
}
catch (AggregateException ae)
{
    // Tratarea excepțiilor, inclusiv OperationCanceledException
    foreach (var e in ae.InnerExceptions)
    {
        if (e is OperationCanceledException)
        {
            Console.WriteLine("Sarcină anulată (prin Wait)." );
        }
        else
        {
            // Tratarea altor excepții
            Console.WriteLine($"Eroare la finalizarea sarcinii: {e.Message}");
        }
    }
}

Console.WriteLine("Programul principal s-a încheiat.");

Alternative:

  • Returnarea unei valori speciale sau a unui flag din sarcină.
  • Verificarea unui flag setat extern, fără a folosi CancellationToken.

Totuși, CancellationToken este abordarea standard și recomandată datorită integrării sale cu Task Parallel Library (TPL), operațiilor asincrone și suportului pentru OperationCanceledException.