Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Les classes System.Threading.Tasks.Task et System.Threading.Tasks.Task<TResult> prennent en charge l'annulation en utilisant des jetons d'annulation. Pour plus d’informations, consultez Annulation dans les threads managés. Dans les classes de tâches, l’annulation implique la coopération entre le délégué utilisateur, qui représente une opération annulable et le code qui a demandé l’annulation. Une annulation réussie implique que le code demandeur appelle la méthode CancellationTokenSource.Cancel et que le délégué utilisateur termine l’opération en temps opportun. Vous pouvez arrêter l’opération à l’aide de l’une des options suivantes :
En revenant du délégué. Dans de nombreux scénarios, cette option est suffisante. Toutefois, une instance de tâche annulée de cette façon passe à l’état TaskStatus.RanToCompletion , et non à l’état TaskStatus.Canceled .
En lançant un OperationCanceledException et en lui passant le jeton sur lequel l’annulation a été demandée. La manière recommandée pour effectuer cela est d'utiliser la méthode ThrowIfCancellationRequested. Une tâche annulée de cette façon passe à l’état annulé, que le code appelant peut utiliser pour vérifier que la tâche a répondu à sa demande d’annulation.
L’exemple suivant montre le modèle de base pour l’annulation de tâche qui lève l’exception :
Remarque
Le jeton est transmis au délégué utilisateur et à l’instance de tâche.
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
Pour obtenir un exemple complet, consultez Comment annuler une tâche et les tâches qui en dépendent.
Lorsqu’une instance de tâche observe un OperationCanceledException levé par le code utilisateur, elle compare le jeton de l’exception à son jeton associé (celui qui a été transmis à l’API qui a créé la tâche). Si les jetons sont identiques et que la propriété du jeton IsCancellationRequested retourne true
, la tâche l’interprète comme une annulation et passe à l'état annulé. Si vous n’utilisez pas une méthode Wait ou WaitAll pour attendre la tâche, alors la tâche définit simplement son état à Canceled.
Si vous attendez une tâche qui passe à l’état Annulé, une exception System.Threading.Tasks.TaskCanceledException (encapsulée dans une exception AggregateException) est levée. Cette exception indique une annulation réussie au lieu d’une situation défectueuse. Par conséquent, la propriété Exception de la tâche retourne null
.
Si la propriété du jeton IsCancellationRequested retourne false
ou si le jeton de l’exception ne correspond pas au jeton de la tâche, OperationCanceledException est traité comme une exception classique, ce qui entraîne la tâche à passer à l’état de faute. La présence d’autres exceptions entraînera également le passage de la tâche à l’état Défaillant. Vous pouvez obtenir l’état de la tâche terminée dans la Status propriété.
Il est possible qu’une tâche continue de traiter certains éléments une fois l’annulation demandée.