Bonjour tout le monde,

J'ai déjà posté mon problème sur msdn, mais j'ai pensé que je pourrais peut être obtenir de l'aide ici.

Je développe avec .NET 4.0 et sur/pour des machines win7 ou 2k8r2 sp1.

Quand une application utilise BeginPeek ou BeginReceive sur une queue privée, et que cette queue est supprimée alors que l'application attend pour l'évènement, l'application crash avec une exception non gérée. Je n'ai trouvé aucun moyen de catch l'exception et donc d’empêcher l'application de crash dans ce cas.

Il n'y a aucun soucis avec les queues publiques. Pas de problème, aussi bien que les queues publiques que privées, en utilisant la librairie COM mqoa.dll à la place de System.Messaging. Cependant la librairie COM à une limitation de 64 inscriptions concurrentes par processus à ce genre d'évènements. Et dans mon cas 64 inscriptions n'est pas assez.

Au début je pensais que mon programme fonctionnerait avec les queues publiques et que donc j'esquiverais le problème comme ça, mais au final non.

J'ajoute un exemple simple de code qui génère cette erreur. Une fois le programme lancé et le BeginReceive passé, il suffit de supprimer manuellement la queue dans l'interface de gestion MSMQ pour que l'application crash. Ici les try/catch ne permettent pas de catch l'exception.

Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 static void Main(string[] args)
  {
   try
   {
    MessageQueue queue = new MessageQueue("FormatName:Direct=OS:.\\Private$\\test");
    queue.ReceiveCompleted += (sender, e) =>
    {
     try
     {
      queue.EndReceive(e.AsyncResult);
      queue.BeginReceive();
     }
     catch (Exception ex)
     {
      Console.WriteLine(ex);
      Console.ReadLine();
     }
    };
    queue.BeginReceive();
    Console.ReadLine();
   }
   catch (Exception e)
   {
    Console.WriteLine(e);
    Console.ReadLine();
   }
  }

J'ajoute aussi la stack trace de l'exception.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
Unhandled Exception: System.Messaging.MessageQueueException: The queue does not exist or you do not have sufficient permissions to perform the operation.
 
   at System.Messaging.MessageQueue.MQCacheableInfo.get_ReadHandle()
   at System.Messaging.MessageQueue.StaleSafeReceiveMessage(UInt32 timeout, Int32 action, MQPROPS properties, NativeOverlapped* overlapped, ReceiveCallback receiveCallback, CursorHandle cursorHandle, IntPtr transaction)
   at System.Messaging.MessageQueue.AsynchronousRequest.RaiseCompletionEvent(Int32 result, NativeOverlapped* overlappedPointer)
   at System.Messaging.MessageQueue.AsynchronousRequest.OnCompletionStatusChanged(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* overlappedPointer)
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
Et aussi le message d'erreur Windows.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
System.Messaging.MessageQueueException occurred
 
  Message=The queue does not exist or you do not have sufficient permissions to perform the operation.
 
  Source=System.Messaging
 
  ErrorCode=-2147467259
 
  StackTrace:
 
       at System.Messaging.MessageQueue.MQCacheableInfo.get_ReadHandle()
 
  InnerException:
Quelqu'un a t'il une solution ?

Merci d'avance !

Vincent.