Je joue avec ces tâches Windows 8 WinRT et j'essaie d'annuler une tâche en utilisant la méthode ci-dessous, et cela fonctionne jusqu'à un certain point. La méthode CancelNotification est appelée, ce qui vous fait penser que la tâche a été annulée, mais en arrière-plan, la tâche continue de s'exécuter, puis une fois terminée, l'état de la tâche est toujours terminé et jamais annulé. Existe-t-il un moyen d'arrêter complètement la tâche lorsqu'elle est annulée?
private async void TryTask()
{
CancellationTokenSource source = new CancellationTokenSource();
source.Token.Register(CancelNotification);
source.CancelAfter(TimeSpan.FromSeconds(1));
var task = Task<int>.Factory.StartNew(() => slowFunc(1, 2), source.Token);
await task;
if (task.IsCompleted)
{
MessageDialog md = new MessageDialog(task.Result.ToString());
await md.ShowAsync();
}
else
{
MessageDialog md = new MessageDialog("Uncompleted");
await md.ShowAsync();
}
}
private int slowFunc(int a, int b)
{
string someString = string.Empty;
for (int i = 0; i < 200000; i++)
{
someString += "a";
}
return a + b;
}
private void CancelNotification()
{
}
Réponses:
Renseignez-vous sur l' annulation (qui a été introduite dans .NET 4.0 et est en grande partie inchangée depuis lors) et le modèle asynchrone basé sur les tâches , qui fournit des instructions sur l'utilisation
CancellationToken
desasync
méthodes.Pour résumer, vous passez un
CancellationToken
dans chaque méthode qui prend en charge l'annulation, et cette méthode doit le vérifier périodiquement.la source
CancellationToken
a tous les hooks nécessaires pour interopérer avec les systèmes d'annulation personnalisés, mais rien ne peut annuler une méthode non annulable.Wait
niResult
dans lesasync
méthodes; vous devriez toujours utiliser à laawait
place, qui déballe l'exception correctement.CancellationToken.IsCancellationRequested
et suggère plutôt de lancer des exceptions?Ou, pour éviter de modifier
slowFunc
(disons que vous n'avez pas accès au code source par exemple):Vous pouvez également utiliser de belles méthodes d'extension à partir de https://github.com/StephenCleary/AsyncEx et avoir l'air aussi simple que:
la source
ConfigureAwait
sinon vous pourriez être blessé dans les applications d'interface utilisateur.using
.Un cas qui n'a pas été couvert est la façon de gérer l'annulation à l'intérieur d'une méthode asynchrone. Prenons, par exemple, un cas simple où vous devez télécharger des données sur un service pour le calculer, puis renvoyer des résultats.
Si vous souhaitez prendre en charge l'annulation, le moyen le plus simple serait de transmettre un jeton et de vérifier s'il a été annulé entre chaque appel de méthode asynchrone (ou en utilisant ContinueWith). S'il s'agit d'appels très longs, vous pourriez attendre un certain temps avant d'annuler. J'ai créé une petite méthode d'aide pour échouer à la place dès l'annulation.
Donc, pour l'utiliser, ajoutez simplement
.WaitOrCancel(token)
à tout appel asynchrone:Notez que cela n'arrêtera pas la tâche que vous attendiez et qu'elle continuera à s'exécuter. Vous aurez besoin d'utiliser un mécanisme différent pour l' arrêter, comme l'
CancelAsync
appel dans l'exemple, ou mieux encore passer dans le mêmeCancellationToken
à laTask
façon qu'il puisse gérer l'annulation par la suite. Il n'est pas recommandé d' essayer d'annuler le thread .la source
UploadDataAsync
peut continuer en arrière-plan, mais une fois terminé, il ne fera pas l'appelCalculateAsync
car cette partie a déjà cessé d'attendre). Cela peut être problématique ou non pour vous, surtout si vous souhaitez réessayer l'opération. Passer leCancellationToken
tout en bas est l'option préférée, lorsque cela est possible.Je veux juste ajouter à la réponse déjà acceptée. J'étais coincé là-dessus, mais j'allais sur une voie différente pour gérer l'événement complet. Plutôt que d'exécuter await, j'ajoute un gestionnaire terminé à la tâche.
Où le gestionnaire d'événements ressemble à ceci
Avec cet itinéraire, toute la gestion est déjà effectuée pour vous, lorsque la tâche est annulée, elle déclenche simplement le gestionnaire d'événements et vous pouvez voir si elle a été annulée à cet endroit.
la source