Sobes.tech
Middle

Hogyan lehet megszakítani egy feladat (task) végrehajtását C#-ban?

sobes.tech MI

Válasz az MI-től

A C#-ban egy feladat megszakításához a CancellationToken és CancellationTokenSource mechanizmust használják.

  1. Létrehozunk egy CancellationTokenSource-t.
  2. A CancellationTokenSource-ból származó CancellationToken-t kapunk.
  3. A CancellationToken-t átadjuk a feladatot végrehajtó metódusnak.
  4. A futó metódusban időről időre ellenőrizzük a IsCancellationRequested tulajdonságot.
  5. Ha a IsCancellationRequested true, akkor egy OperationCanceledException-t generálunk vagy más végrehajtási logikát alkalmazunk.
  6. A megszakítás kéréséhez a CancellationTokenSource-on a Cancel() metódust hívjuk meg.

Használati példa:

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

// Megszakítási token forrás létrehozása
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;

// Feladat létrehozása
Task task = Task.Run(() =>
{
    try
    {
        for (int i = 0; i < 100; i++)
        {
            // Ellenőrzés, hogy kértek-e megszakítást
            if (token.IsCancellationRequested)
            {
                // OperationCanceledException generálása
                token.ThrowIfCancellationRequested();
            }

            // Munka szimulálása
            Console.WriteLine($"Dolgozom... {i}");
            Thread.Sleep(100);
        }
    }
    catch (OperationCanceledException)
    {
        // Megszakítás kezelése
        Console.WriteLine("A feladat megszakadt.");
    }
    catch (Exception ex)
    {
        // Egyéb kivételek kezelése
        Console.WriteLine($"Hiba történt: {ex.Message}");
    }
}, token); // Token átadása a feladatnak

// Várunk egy kicsit, majd kérjük a megszakítást
Thread.Sleep(500);
Console.WriteLine("Megszakítás kérve...");
cts.Cancel();

// Várunk a feladat befejezésére
try
{
    task.Wait();
}
catch (AggregateException ae)
{
    // Kivételek kezelése, beleértve az OperationCanceledException-t
    foreach (var e in ae.InnerExceptions)
    {
        if (e is OperationCanceledException)
        {
            Console.WriteLine("A megszakított feladat befejeződött (Wait-en keresztül)." );
        }
        else
        {
            // Egyéb kivételek kezelése
            Console.WriteLine($"Hiba a feladat befejezésekor: {e.Message}");
        }
    }
}

Console.WriteLine("A fő program befejeződött.");

Alternatívák:

  • Különleges érték vagy zászló visszaadása a feladatból.
  • Külsőleg beállított zászló ellenőrzése CancellationToken használata nélkül.

Azonban a CancellationToken a szabványos és ajánlott megközelítés, mivel jól integrálódik a Task Parallel Library (TPL), az aszinkron műveletekkel és támogatja az OperationCanceledException-t.