Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Třídy System.Threading.Tasks.Task a System.Threading.Tasks.Task<TResult> podporují zrušení pomocí tokenů zrušení. Další informace naleznete v části 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 kód, který volá metodu CancellationTokenSource.Cancel a delegát uživatele, který včas ukončí operaci. Operaci můžete ukončit pomocí jedné z těchto možností:
Návratem od delegáta. V mnoha scénářích je tato možnost dostačující. Avšak instance úlohy, která je tímto způsobem zrušena, přejde do TaskStatus.RanToCompletion stavu, nikoli do TaskStatus.Canceled stavu.
Při vyvolání OperationCanceledException a předání tokenu, který signalizuje požadavek na zrušení. Upřednostňovaným způsobem, jak provádět, je použít metodu ThrowIfCancellationRequested. Ú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, je vyvolána výjimka System.Threading.Tasks.TaskCanceledException (zabalená do výjimky AggregateException). 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. Stav dokončeného úkolu můžete získat ve vlastnosti Status.
Je možné, že úkol může po vyžádání zrušení dál zpracovávat některé položky.