Frage

Soweit ich aus der Dokumentation sehen kann, wie Sie angeblich zu prüfen, ob Nachrichten in einer Nachrichtenwarteschlange sind, ist die Peek-Methode zu verwenden. Sie verlassen sich dann auf sie mit einem Message Fehler, Ihnen zu sagen, dass die Warteschlange leer war.

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

Ich habe immer gesagt worden - und erlebt haben - das Exeptions teuer sind, und sollte nicht für den normalen Betrieb verwendet werden. Also meine Fragen sind:

  • Sind meine Annahmen, dass auf den Fang der Message Berufung ist ein kostspieliger Vorgang korrekt?

  • Gibt es eine Möglichkeit, synchron zu prüfen, ob Nachrichten in einer Warteschlange sind, ohne auf Ausnahmen verlassen zu müssen?

Ich arbeite mit dem System.Messaging Namespace in C #, aber wenn ich brauchen würde, nicht verwalteten zu gehen, dies zu lösen, die eine Option sein könnten. Und beachten Sie, dass ich eine Lösung wollen, ohne WCF mit MSMQ zu verwenden.

War es hilfreich?

Lösung

Update: Ich behaupte nicht, dass die Leistung nicht wichtig ist. Aber ich denke, dass Inter-Prozess-Kommunikation im Vergleich zu Ausnahme sehr teuer ist.

Vor dem Update:

  • Ich denke, dass im Rahmen der Interprozesskommunikation (das ist, was msmq der Fall ist) die Kosten für die Ausnahme unwichtig ist. Testen Sie, ob Sie wollen sicher sein.
  • Ich glaube nicht.

Andere Tipps

  • Ja, Sie sind richtig in der Annahme, dass Ausnahmen teuer sind. Eigentlich ist es das Werfen, das teuer ist, nicht zu kontrollieren. Es ist normal für eine Warteschlange manchmal leer zu sein, und ein normaler Zustand sollte nicht führen zu einer Ausnahme ausgelöst wird.

  • Durch die Verwendung von MessageQueue.GetMessageEnumerator2 wir den Enumerator verwenden könnten, um zu bestimmen, ob eine Warteschlange leer ist oder nicht, ohne alle Nachrichten zu laden. Mit diesem Ansatz würden wir nie mehr als eine Nachricht laden.

Beispiel:

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

oder Peek zu implementieren, die null zurückgibt, wenn die Nachrichtenwarteschlange leer ist (nicht getestet, sollte aber funktionieren)

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

Wir benutzten Code wie das Original über zwanzig verschiedene Warteschlangen zu überprüfen. Da wir von der ursprünglichen Implementierung einen geändert Ich schlage vor, erhöhte die Geschwindigkeit unserer Importe drastisch, da die CPU mehr verwendet werden könnten, Nachrichten zu verarbeiten, anstatt die Verarbeitung führt.

MSMQ ist nicht ganz übergreifende Kommunikation. Interprozess-Kommunikation ist meist in einzelner Maschine aber msmq kann die Kommunikation für verschiedene Computer verwendet werden. Guarenteed Lieferung, mit Kehrseite in gleichen OS haben.

Wie wäre es versucht mq.GetAllMessages (). Länge> 0

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top