Zrušení úkolu
Třídy System.Threading.Tasks.Task podporují System.Threading.Tasks.Task<TResult> zrušení pomocí tokenů zrušení. Další informace najdete v tématu Zrušení ve spravovaných vláknech. V třídách úkolů zahrnuje zrušení spolupráci mezi delegátem uživatele, který představuje operaci zrušitelnou a kód, který požadoval zrušení. Úspěšné zrušení zahrnuje žádost o kód volající metodu CancellationTokenSource.Cancel a delegát uživatele ukončuje operaci včas. Operace může být ukončena pomocí jedné z těchto možností:
Vrácením od delegáta. V mnoha scénářích je tato možnost dostatečná. Instance úlohy, která je tímto způsobem zrušena, se ale převede do TaskStatus.RanToCompletion stavu, nikoli do TaskStatus.Canceled stavu.
OperationCanceledException Vyvoláním a předáním tokenu, na kterém bylo požadováno zrušení. Upřednostňovaným způsobem provedení je použití ThrowIfCancellationRequested metody. Úkol, který se tímto způsobem zruší, přejde do zrušeného stavu, který může volající kód použít k ověření, že úkol odpověděl na žádost o zrušení.
Následující příklad ukazuje základní vzor pro zrušení úkolu, který vyvolá výjimku:
Poznámka
Token se předá delegátu uživatele a instanci úlohy.
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
var tokenSource2 = new CancellationTokenSource();
CancellationToken ct = tokenSource2.Token;
var task = Task.Run(() =>
{
// Were we already canceled?
ct.ThrowIfCancellationRequested();
bool moreToDo = true;
while (moreToDo)
{
// Poll on this property if you have to do
// other cleanup before throwing.
if (ct.IsCancellationRequested)
{
// Clean up here, then...
ct.ThrowIfCancellationRequested();
}
}
}, tokenSource2.Token); // Pass same token to Task.Run.
tokenSource2.Cancel();
// Just continue on this thread, or await with try-catch:
try
{
await task;
}
catch (OperationCanceledException e)
{
Console.WriteLine($"{nameof(OperationCanceledException)} thrown with message: {e.Message}");
}
finally
{
tokenSource2.Dispose();
}
Console.ReadKey();
}
}
Imports System.Threading
Imports System.Threading.Tasks
Module Test
Sub Main()
Dim tokenSource2 As New CancellationTokenSource()
Dim ct As CancellationToken = tokenSource2.Token
Dim t2 = Task.Factory.StartNew(Sub()
' Were we already canceled?
ct.ThrowIfCancellationRequested()
Dim moreToDo As Boolean = True
While moreToDo = True
' Poll on this property if you have to do
' other cleanup before throwing.
If ct.IsCancellationRequested Then
' Clean up here, then...
ct.ThrowIfCancellationRequested()
End If
End While
End Sub _
, tokenSource2.Token) ' Pass same token to StartNew.
' Cancel the task.
tokenSource2.Cancel()
' Just continue on this thread, or Wait/WaitAll with try-catch:
Try
t2.Wait()
Catch e As AggregateException
For Each item In e.InnerExceptions
Console.WriteLine(e.Message & " " & item.Message)
Next
Finally
tokenSource2.Dispose()
End Try
Console.ReadKey()
End Sub
End Module
Úplný příklad najdete v tématu Postupy: Zrušení úkolu a jeho podřízených položek.
Když instance úlohy sleduje OperationCanceledException vyvolání uživatelským kódem, porovná token výjimky s přidruženým tokenem (ten, který byl předán rozhraní API, které vytvořilo úlohu). Pokud jsou tokeny stejné a vlastnost tokenu IsCancellationRequested vrátí true
, úloha to interpretuje jako potvrzení zrušení a přechody do zrušeného stavu. Pokud k čekání na úkol nepoužíváte metodu Wait nebo WaitAll ji nepoužíváte, nastaví úkol jeho stav na Canceled.
Pokud čekáte na úkol, který přejde do zrušeného stavu, System.Threading.Tasks.TaskCanceledException vyvolá se výjimka (zabalená v výjimce AggregateException ). Tato výjimka označuje úspěšné zrušení místo chybné situace. Proto vlastnost úkolu Exception vrátí null
.
Pokud vlastnost tokenu IsCancellationRequested vrátí false
nebo pokud token výjimky neodpovídá tokenu úkolu, OperationCanceledException je považován za normální výjimku, což způsobí, že úloha přejde do chybného stavu. Přítomnost dalších výjimek také způsobí, že úloha přejde do chybného stavu. Stav dokončeného úkolu můžete získat ve Status vlastnosti.
Je možné, že úkol může po vyžádání zrušení pokračovat ve zpracování některých položek.