Pregunta

Hasta donde puedo ver en la documentación, la forma en que se supone que debe verificar si hay mensajes en una cola de mensajes es usar el método Peek. Luego confía en que falla con una MessageQueueException para decirle que la cola estaba vacía.

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

Siempre me han dicho, y he experimentado, que las excepciones son costosas y no deben usarse para operaciones normales. Entonces mis preguntas son:

  • ¿Son correctas mis suposiciones de que confiar en la captura de MessageQueueException es una operación costosa?

  • ¿Hay alguna forma de verificar sincrónicamente si hay mensajes en una cola sin tener que depender de excepciones?

Estoy trabajando con el espacio de nombres System.Messaging en C #, pero si tuviera que quedar sin administrar para resolver esto, esa podría ser una opción. Y tenga en cuenta que quiero una solución sin usar WCF con MSMQ.

¿Fue útil?

Solución

Actualización: no afirmo que el rendimiento no sea importante. Pero creo que la comunicación entre procesos es muy cara en comparación con la excepción.

Antes de la actualización:

  • Creo que en el contexto de la comunicación entre procesos (que es lo que hace msmq), el costo de la excepción no es importante. Prueba si quieres estar seguro.
  • No lo creo.

Otros consejos

  • Sí, tiene razón en el supuesto de que las excepciones son costosas. En realidad es el lanzamiento lo que es caro, no la captura. Es normal que una cola esté vacía a veces y un estado normal no debe generar una excepción.

  • Al usar MessageQueue.GetMessageEnumerator2 podríamos usar el enumerador para determinar si una cola está vacía o no sin cargar todos los mensajes. Con este enfoque, nunca cargaríamos más de un mensaje.

Ejemplo:

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

o para implementar Peek que devuelve nulo si la cola de mensajes está vacía (sin probar, pero debería funcionar)

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

Utilizamos código como el original para verificar unas veinte colas diferentes. Dado que cambiamos de la implementación original a la que sugiero, la velocidad de nuestras importaciones aumentó drásticamente ya que la CPU podría usarse más para procesar mensajes en lugar de procesar lanzamientos.

MSMQ no es completamente comunicación entre procesos. La comunicación entre procesos se realiza principalmente en una sola máquina, pero msmq se puede usar para diferentes computadoras que se comunican. Entrega garantizada, con la otra cara de tener en el mismo sistema operativo.

¿qué tal probar mq.GetAllMessages (). Longitud > 0

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top