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.
- Sukuriamas
CancellationTokenSource. - Iš
CancellationTokenSourcegaunamasCancellationToken. CancellationTokenperduodamas į metodą, kuris vykdo užduotį.- Viduje vykdomo metodo periodiškai tikrinama
IsCancellationRequestedsavybė. - Jei
IsCancellationRequestedyratrue, generuojamaOperationCanceledExceptionarba atliekama kita užbaigimo logika. - Norint prašyti atšaukimo, iškviečiama
Cancel()metodoCancellationTokenSourceobjekte.
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.