Domanda

Per quanto posso vedere dalla documentazione, il modo in cui dovresti controllare se ci sono messaggi in una coda di messaggi è usare il metodo Peek. Quindi fai affidamento sul fatto che fallisce con MessageQueueException per dirti che la coda era vuota.

    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;
    }

Mi è sempre stato detto - e ho sperimentato - che le eccezioni sono costose e non dovrebbero essere utilizzate per le normali operazioni. Quindi le mie domande sono:

  • Le mie ipotesi sono che l'operazione di acquisizione di MessageQueueException sia un'operazione costosa corretta?

  • Esiste un modo per verificare in modo sincrono se ci sono messaggi in una coda senza fare affidamento su eccezioni?

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

È stato utile?

Soluzione

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

Prima dell'aggiornamento:

  • Penso che nel contesto della comunicazione tra processi (che è ciò che fa msmq) il costo dell'eccezione non è importante. Prova se vuoi esserne sicuro.
  • Non credo.

Altri suggerimenti

  • Sì, hai ragione nel presupporre che le eccezioni siano 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.

  • Usando MessageQueue.GetMessageEnumerator2 potremmo usare l'enumeratore per determinare se una coda è vuota o meno senza caricare tutti i messaggi. Con questo approccio non avremmo mai caricato 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 dei messaggi è vuota (non testata, ma dovrebbe funzionare)

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

Abbiamo usato codice come l'originale per controllare una ventina di code diverse. Da quando siamo passati dall'implementazione originale a quella che suggerisco, la velocità delle nostre importazioni è aumentata drasticamente poiché la CPU potrebbe essere utilizzata maggiormente per elaborare i messaggi anziché elaborare i lanci.

MSMQ non è una comunicazione interamente tra processi. La comunicazione tra processi avviene principalmente su un singolo computer, ma msmq può essere utilizzato per diversi computer in comunicazione. Consegna garantita, con il rovescio della medaglia di avere nello stesso sistema operativo.

che ne dici di provare mq.GetAllMessages (). Lunghezza > 0

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top