2016-10-19 1 views
1

Il semble que juste après avoir appelé ma première méthode asynchrone (GetBar() dans cet exemple), le IsCancellationRequested de CancellationToken est défini sur true, mais je ne le veux pas et je ne comprends pas pourquoi cela se produit.Pourquoi ce CancellationToken est-il annulé?

Il s'agit d'un rôle de travail Azure Cloud Service, si cela est important. J'ai déjà utilisé avec succès CancellationTokens une fois auparavant dans un autre projet et j'utilise une configuration similaire ici. La seule différence dont je suis au courant est qu'il s'agit d'un service cloud Azure. Une idée de pourquoi IsCancellationRequested est réglé à vrai?

+1

Quel autre code touche 'cancellationTokenSource' outre les deux lignes que vous avez montré dans' Run() ', peut également'Exécuter()' être appelé plusieurs fois? Si je devais deviner je dirais que vous avez une condition de concurrence avec le 'this.cancellationTokenSource.Token' à l'intérieur de la lambada et que le jeton est passé à' Foo.Bar ('ne pas être le même jeton qui a été passé en tant que deuxième paramètre de 'Task.Run (' –

+1

Obtenez-vous une exception levée pour 'GetBar'? Vérifiez ceci, et voyez si cela aide: http://stackoverflow.com/questions/13489065/best-practice- to-call-configureawait-for-all-server-side-code –

+1

Par votre mise à jour, 'OnStop' a-t-il pu être appelé pendant que vous attendiez que' FooService.GetBar() 'soit terminé? Peut-être ajouter une forme de journalisation pour voir si 'OnStop' est appelé entre avant le' token.ThrowIfCancellationRequested(); 'et après le' var bar = wait ... ' –

Répondre

1

Il semble que OnStop ait été appelé pendant que vous attendiez FooService.GetBar() pour terminer. Peut-être ajouter une forme de journalisation pour voir si OnStop est appelée entre le token.ThrowIfCancellationRequested(); et après les retours var bar = await ... pour confirmer.

C'est ce qui provoque l'annulation du jeton.

Pour résoudre le problème, vous devez vous assurer que the overridden Run method does not return till the work is complete.

public override void Run() 
{ 
    this.cancellationTokenSource = new CancellationTokenSource(); 
    this.runTask = Task.Run(() => Foo.Bar(this.cancellationTokenSource.Token), this.cancellationTokenSource.Token); 
    this.runTask.Wait(); //You may need a try/catch around it 
} 
+0

Juste pour clarifier, la raison pour laquelle 'OnStop' est appelé est parce que ma méthode' Run' finit par retourner. Trouvé cette information ici: https://azure.microsoft.com/fr-fr/documentation/articles/cloud-services-role-lifecycle-dotnet/#run-method – MattM

+0

Fait sens. Mise à jour ma réponse pour inclure l'information. –