Vous pouvez annuler le travail de l'étape 2 en utilisant un CancellationToken et/ou attendre le code de traitement de message asynchrone à l'étape 4 avant d'attendre l'appel de queueClient.CloseAsync(). Je suppose que vous êtes familier avec Tasks and Cancellation.
tâche de traitement des messages Attendent
Initialiser un client de file d'attente queueClient
et stocker une référence dans le cadre global de la classe
client file d'attente gère un message et appelle un code d'application pour le gérer, ce qui pourrait finir par faire un travail de base de données asynchrone ou appeler une API distante, par exemple public Task HandleMessageAsync() {..}
. Stocker une référence à cette tâche dans la portée globale de la classe. Par exemple private Task messageHandleTask;
Considérons l'application est un service Windows avec une méthode CloseAsync
qui est signalée lorsque le service doit être arrêté. Dans cette méthode j'appelle d'abord await messageHandleTask
puis await queueClient.CloseAsync()
Nous vivons tous longtemps et heureusement.
Dans ce scénario, le service ne sera pas complètement arrêté jusqu'à ce que la gestion des messages soit terminée.
Annuler tâche de traitement des messages
Initialiser un client de file d'attente queueClient
et stocker une référence dans le cadre global de la classe
client file d'attente gère un message et demande un code d'application pour le gérer, en passant par un CancellationToken
, qui pourrait finir par faire un travail de base de données asynchrone ou appeler une API distante, par exemple public Task HandleMessageAsync(CancellationToken token) {..}
. Stocker une référence à cette tâche dans la portée globale de la classe. Considérons que l'application est un service Windows avec une méthode CloseAsync
qui est signalée lorsque le service doit être arrêté. Dans cette méthode j'appelle d'abord cancellationTokenSource.Cancel()
, puis await messageHandleTask
et enfin await queueClient.CloseAsync()
Nous vivons tous longtemps et heureusement.
Dans ce scénario, dans le code de gestion des messages, juste avant l'appel à message.Complete().
vous vérifier pour toute annulation: token.ThrowIfCancellationRequested
. Dans ce cas, lorsque le service est fermé, le message n'atteint jamais l'état terminé et sera traité plus tard. (Soyez conscient, je ne connais pas le code impliqué donc ce scénario pourrait être complexe si le travail est déjà en partie fait avant que l'annulation se produise) Assurez-vous de gérer OperationCanceledException
.
Dans un scénario où plusieurs messages sont traités en même temps, vous pouvez utiliser await Task.WhenAll(..)
Par ailleurs, si cette suites de réponse que vous, envoyez-moi un muffin, ils semblent délicieux ;-) –
Merci pour la réponse détaillée. Pour être clair, je préfèrerais ne pas introduire la complexité de l'annulation des changements partiels sur lesquels l'application travaillait lors de la gestion d'un message, je préfère le laisser finir avant de permettre la fermeture du service, donc le premier exemple être le plus simple et ce que je fais actuellement est la bonne façon? J'avais supposé, puisque l'attente laisserait l'exécution du programme continuer alors qu'il attendait sur la base de données, qu'il permettrait à la méthode 'queueClient.CloseAsync' d'être appelée avant que la base de données renvoyé le contrôle à l'application. –
Le premier exemple correspond le mieux à votre scénario, en effet. Si vous attendez la méthode qui communique d'abord avec de base de données, puis attendez l'appel à 'queueClient.CloseAsync()' alors vous pouvez être assuré que la première tâche est terminée avant l'appel pour fermer le client. –