2009-09-17 8 views
6

Per quanto posso vedere dalla documentazione, il modo in cui si suppone di controllare se ci sono messaggi in una coda di messaggi è di usare il metodo Peek. In tal caso, si fa affidamento su di esso con un errore MessageQueueException per indicare che la coda era vuota.Posso dare un'occhiata a MSMQ vuoto senza ottenere eccezioni?

public bool IsQueueEmpty() 
    { 
     bool isQueueEmpty = false; 
     MessageQueue myQueue = new MessageQueue(".\\myQueue"); 

     try 
     { 
      myQueue.Peek(new TimeSpan(0)); 
      isQueueEmpty = false; 
     } 

     catch(MessageQueueException e) 
     { 
      if (e.MessageQueueErrorCode == 
       MessageQueueErrorCode.IOTimeout) 
      { 
       isQueueEmpty = true; 
      } 
     } 
     return isQueueEmpty; 
    } 

Sono sempre stato detto - e hanno sperimentato - che exeptions sono costosi, e non deve essere utilizzato per le normali operazioni. Quindi le mie domande sono:

  • sono le mie supposizioni che basandosi su di prendere il MessageQueueException è un'operazione costosa corretta?

  • C'è un modo per verificare in modo sincrono se ci sono messaggi in una coda senza dover fare affidamento sulle eccezioni?

sto lavorando con lo spazio dei nomi System.Messaging in C#, ma se avrei bisogno di andare non gestito per risolvere questo che potrebbe essere un'opzione. E nota che voglio una soluzione senza usare WCF con MSMQ.

risposta

1

Aggiornamento: Non ritengo che le prestazioni non siano importanti. Ma penso che la comunicazione tra processi sia molto costosa rispetto all'eccezione.

Prima aggiornamento:

  • Credo che nel contesto di comunicazione tra processi (che è quello che fa MSMQ) il costo di eccezione è irrilevante. Prova se vuoi essere sicuro.
  • Non credo.
+0

Passiamo i messaggi attraverso una pipeline di servizi in cui utilizziamo le code tra di loro. Vogliamo avere il massimo rendimento possibile, quindi non è poco importante, ma finora abbiamo prestazioni abbastanza buone. –

+0

Aspetterò di vedere se ottengo altri commenti, ma se non accetto accetterò la tua risposta: | –

-1

MSMQ non è una comunicazione completamente interprocesso. La comunicazione tra processi è per lo più in una singola macchina, ma msmq può essere utilizzato per diversi computer che comunicano. Consegna garantita, con il rovescio della medaglia di avere nello stesso sistema operativo.

-2

come su mq.GetAllMessages cercano(). Lunghezza> 0

+4

Davvero? Anche quando la tua coda potrebbe contenere 1000 o 10.000 di messaggi di grandi dimensioni? È come mangiare l'intero supermercato vuoto solo perché vuoi sapere se hanno lasciato qualche mela. –

11
  • Sì hai ragione nel presupposto che le eccezioni sono costose. In realtà è il lancio che è costoso, non la cattura. È normale che una coda sia vuota a volte e uno stato normale non dovrebbe comportare il lancio di un'eccezione.

  • Utilizzando MessageQueue.GetMessageEnumerator2 è possibile utilizzare l'enumeratore per determinare se una coda è vuota o meno senza caricare tutti i messaggi. Con questo approccio non caricaremmo più di un messaggio.

Esempio:

private static bool IsQueueEmpty(MessageQueue queue) 
{ 
    using (var enumerator = queue.GetMessageEnumerator2()) 
    { 
     return !enumerator.MoveNext(); 
    } 
} 

o per implementare Peek che restituisce null se la coda di messaggi è vuota (non testato, ma dovrebbe funzionare)

private static Message Peek(MessageQueue queue) 
{ 
    using (var enumerator = queue.GetMessageEnumerator2()) 
    { 
     return enumerator.MoveNext() ? enumerator.Current : null; 
    } 
} 

Abbiamo usato il codice come l'originale a controlla circa venti diverse code.Dal momento che siamo passati dall'implementazione originale a quella che suggerisco, la velocità delle nostre importazioni è aumentata drasticamente poiché la CPU potrebbe essere utilizzata di più per elaborare i messaggi anziché i lanci di elaborazione.

+0

Questa dovrebbe essere la risposta accettata. –