Comment transformer task.Wait (CancellationToken) à une déclaration d’attente?

Donc, task.Wait() peut être transformé en await task . La sémantique est différente, bien sûr, mais c’est à peu près ce que je ferais pour transformer un code bloquant avec Waits en un code asynchrone avec awaits .

Ma question est de savoir comment transformer task.Wait(CancellationToken) à la déclaration d’ await respective?

Créer une nouvelle Task qui représente une tâche existante mais avec un jeton d’annulation supplémentaire est assez simple. Il vous suffit d’appeler ContinueWith pour la tâche, d’utiliser le nouveau jeton et de propager le résultat / les exceptions dans le corps de la suite.

 public static Task WithCancellation(this Task task, CancellationToken token) { return task.ContinueWith(t => t.GetAwaiter().GetResult(), token); } public static Task WithCancellation(this Task task, CancellationToken token) { return task.ContinueWith(t => t.GetAwaiter().GetResult(), token); } 

Cela vous permet d’écrire task.WithCancellation(cancellationToken) pour append un jeton à une tâche, que vous pouvez ensuite await .

await est utilisé pour les méthodes / delegates asynchrones, qui acceptent un CancellationToken et vous devez donc en passer un lorsque vous l’appelez (c.-à-d. await Task.Delay(1000, cancellationToken) ), ou bien ils ne peuvent pas être annulés. (par exemple, attendre un résultat d’E / S).

Cependant, vous pouvez abandonner * ce type de tâches avec cette méthode d’extension:

 public static Task WithCancellation(this Task task, CancellationToken cancellationToken) { return task.IsCompleted // fast-path optimization ? task : task.ContinueWith( completedTask => completedTask.GetAwaiter().GetResult(), cancellationToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); } 

Usage:

 await task.WithCancellation(cancellationToken); 

* La tâche abandonnée n’est pas annulée, mais votre code se comporte comme s’il l’avait été. Il se termine avec un résultat / exception ou il restra en vie pour toujours.