6
votes

Est-il possible de perdre des messages à l'aide de MSMQ MessageQuez.Pek avec un délai d'expiration?

Je suis actuellement en train de perdre un message. Cette erreur se produit rarement, mais se produit assez souvent pour être ennuyeux. Voici le contexte de la question:


0 commentaires

3 Réponses :


5
votes

Je ne pense pas que les messages soient manqués en fonction d'un examen rapide, mais vous travaillez de manière très étrange avec beaucoup de possibilités de conditions de course.

Pourquoi ne pas simplement recevoir le message et le transmettre à ProcessMessage (si ProcessMessage échoue, vous effectuez une lecture de toute façon). Si vous avez besoin de gérer plusieurs récepteurs, effectuez la réception dans une transaction MSMQ afin que le message soit indisponible par d'autres récepteurs, mais non retiré de la file d'attente jusqu'à ce que la transaction soit commise.

Aussi, plutôt que d'interroger la file d'attente, pourquoi ne pas recevoir une réception asynchrone et laisser le piscine de thread gérer l'achèvement (où vous devez appeler endreceive ). Cela sauve attacher un fil, et vous n'avez pas besoin d'une fermeture d'un service de cas spécial (fermez la file d'attente de messagerie, puis appelle message ceinture.clearconnectioncache (); ).

En outre, abandonner le thread est un moyen vraiment mauvais de sortir, il suffit de revenir de la fonction de démarrage du fil.



1
votes

Je dois être ce changement couranteMessage = q.eek (nouveau Timespan (0,0,30)); à actuelMessage = q.receive (); va réparer votre problème. J'utilise MSMQ pour un message qui passe dans le même contexte, mais utilisez uniquement le coup d'œil (et attendre une exception de délai d'expiration) pour déterminer si la file d'attente est vide. L'appel à recevoir bloque cependant alors planez-plan en conséquence.

Edit: aussi pour votre récaptation d'exception - Vous pouvez vérifier si votre exception est une exception temporelle en comparant le code d'erreur. < Pré> xxx

où MQE est votre exception de la file d'attente de message. Vous pouvez aimer cela mieux qu'une comparaison de chaîne.


1 commentaires

J'utilise message rsp = colastatus.receivebycorrélationid (corrélationid, nouvelle trimestre (0, délai d'attente, 0)); . Je suis confus si 5 minutes est très élevée pour le délai d'attente. IMHO, je pense que mieux est inférieur à 1 minute.



3
votes

Quelques commentaires pour clarifier comment MSMQ fonctionne ici.

"Je peux prouver que le message est inséré dans GoldMine_Service_Queue car le message apparaît dans le journal de messagerie.

Le message passe dans la file d'attente du journal lorsque le message d'origine est supprimé du GoldMine_Service_Queue. Vous pouvez donc dire que le message a été livré avec succès à la file d'attente et retiré avec succès de la file d'attente.

"Je soupçonne fortement que mon problème puisse se rapporter à la messagerie d'un message et du comportement Time Out."

Un coup d'oeil ne fait rien pour supprimer le message de la file d'attente. Seulement "Q.Receive ();" est-ce que. Dans votre code, il n'y a pas de connexion explicite entre le message qui a été découvert et celui reçu. "Q.Receive ();" Dit juste "recevoir un message de la file d'attente". Dans un environnement multi-threadé, vous pouvez vous attendre à avoir des messages de lecture de manière incohérente - certains pouvaient être découverts et traités plusieurs fois. Vous devriez obtenir l'identifiant du message d'un coup d'œil et utiliser RECEVÉBYID afin que vous ne puissiez recevoir que le message d'un coup d'œil.


0 commentaires