Zrušení úkolu
Třídy System.Threading.Tasks.Task podporují System.Threading.Tasks.Task<TResult> zrušení pomocí tokenů zrušení. Další informace naleznete v tématu Zrušení ve spravovaných vláknech. Ve třídách úloh zahrnuje zrušení spolupráci mezi delegátem uživatele, který představuje zrušitelnou operaci, a kód, který požadoval zrušení. Úspěšné zrušení zahrnuje požadavek na kód volající metodu CancellationTokenSource.Cancel a delegát uživatele ukončující operaci včas. Operace může být ukončena pomocí jedné z těchto možností:
Vrácením delegáta. V mnoha scénářích je tato možnost dostačující. Instance úlohy, která je tímto způsobem zrušena, ale přejde do TaskStatus.RanToCompletion stavu, nikoli do TaskStatus.Canceled stavu.
Vyvoláním OperationCanceledException a předáním tokenu, na kterém bylo požadováno zrušení. Upřednostňovaným způsobem, jak tuto metodu ThrowIfCancellationRequested provést, je použít. Úloha, která je tímto způsobem zrušena, přejde do zrušeného stavu, který volající kód může použít k ověření, že úloha odpověděla na žádost o zrušení.
Následující příklad ukazuje základní vzor pro zrušení úlohy, 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 zaznamená 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 stavu Zrušeno. Pokud k čekání na úlohu nepoužíváte metodu Wait nebo WaitAll ji nepoužíváte, nastaví úloha pouze její stav na Canceled.
Pokud čekáte na úkol, který přejde do stavu Zrušeno, System.Threading.Tasks.TaskCanceledException vyvolá se výjimka (zabalená do AggregateException výjimky). Tato výjimka značí úspěšné zrušení místo chybné situace. Proto vlastnost úkolu Exception vrátí null
.
Pokud se vlastnost tokenu IsCancellationRequested vrátí false
nebo pokud token výjimky neodpovídá tokenu úkolu, OperationCanceledException považuje se 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. Ve vlastnosti můžete získat stav dokončeného úkolu Status .
Je možné, že úkol může po vyžádání zrušení dál zpracovávat některé položky.