Analog der Warteschlange.Peek() für die BlockingCollection beim hören der Konsum von IEnumerable<T>

Ich bin mit Rohrleitungen Muster Implementierung zu entkoppeln Nachrichten, die Verbraucher von einem Hersteller zu vermeiden, slow-Verbraucher-Problem.

Im Falle einer Ausnahme auf eine message-Verarbeitung Bühne [1] es verloren und nicht entsandt, um eine andere Dienst - /Schicht [2]. Wie kann ich damit umgehen, wie Problem in [3] also die Nachricht, nicht verloren gehen, und was Ihnen wichtig ist! Reihenfolge der Nachrichten wird nicht gemischt werden, so dass Ober-Dienst/Schicht werden Nachrichten in der Reihenfolge, wie Sie kamen. Ich habe eine Idee, die beinhaltet eine andere intermediate Queue aber es scheint Komplex? Leider BlockingCollection<T> nicht auszusetzen, Analog Queue.Peek() Methode, so kann ich nur Lesen, nächsten verfügbaren Nachricht und im Falle der erfolgreichen Verarbeitung Dequeue()

private BlockingCollection<IMessage> messagesQueue;    

//TPL Task does following:
//Listen to new messages and as soon as any comes in - process it
foreach (var cachedMessage in 
             messagesQueue.GetConsumingEnumerable(cancellation))
{    
    const int maxRetries = 3;
    int retriesCounter = 0;
    bool isSent = false;

    //On this point a message already is removed from messagesQueue
    while (!isSent && retriesCounter++ <= maxRetries)
    {
        try
        {
           //[1] Preprocess a message
           //[2] Dispatch to an other service/layer    
           clientProxyCallback.SendMessage(cachedMessage);
           isSent = true;
        }                                
        catch(Exception exception)
        {
           //[3]   
           //logging
           if (!isSent && retriesCounter < maxRetries)
           {
              Thread.Sleep(NSeconds);
           }
        }            

        if (!isSent && retriesCounter == maxRetries)
        {
           //just log, message is lost on this stage!
        }
    }
}

BEARBEITEN: habe Vergessen zu sagen, das ist IIS gehosteten WCF-Dienst die Nachrichten verteilt zurück zur Silverlight-client, WCF-Proxy via client-callback-Vertrag.

EDIT2: Unten ist, wie würde ich dies tun, mit Peek(), Bin ich etwas fehlt?

bool successfullySent = true;
try
{
   var item = queue.Peek();
   PreProcessItem(item);
   SendItem(item);       
}
catch(Exception exception)
{
   successfullySent = false;
}
finally
{
   if (successfullySent)
   {
       //just remove already sent item from the queue
       queue.Dequeue();
   }
}

EDIT3: Sicherlich kann ich verwenden alten Stil Ansatz mit while-Schleife bool flag, Queue und AutoResetEvent, aber ich Frage mich, ob das selbe ist auch mit BlockingCollection und GetConsumingEnumerable() ich denke, Einrichtung wie Peek wäre
sehr hilfreich bei Verwendung zusammen mit aufwändig Durchlaufen werden, da sonst alle Pipeline-pattern-Umsetzung Beispiele neue Sachen wie BlockingCollection und GetConsumingEnumerable() sieht nicht haltbar und ich haben gelangen Sie zurück zum alten Konzept.

  • Erwarten Sie, dass die exception nicht geworfen werden, wenn Sie es erneut versuchen? Wenn ja, einfach eine while-Schleife, bis keine exception geworfen. Wenn nicht, müssen Sie entscheiden, was zu tun ist, wenn ein Element nicht verarbeitet werden kann. Vielleicht pass eine Fehlermeldung an die nächste Schicht?
  • Dies ist der server, WCF-service, welches Versand-Nachricht an einen client-proxy kann es sein, dass, wenn Verbindung fehlgeschlagen, und in 5 Sekunden-client Verbindung zu einem Dienst und bereit zum empfangen von Nachrichten, while Schleife ist, was mache ich jetzt mit N Wiederholungen senden, muss ich erwähnen, es ist aber immer die Frage, welches Magische Zahl für reconectRetries und timeout zu wählen
  • Es klingt wie Sie sind auf dem Weg zu erfinden, message queues. Haben Sie sich überlegt mit so etwas wie MSMQ oder RabbitMQ?
  • Dies ist eine schwere Technik, Im nicht sicher, dass dies der beste Weg zu gehen, für den WCF service?! aber muss zugeben es ist sehr robust und zuverlässig
  • Und warum denkst du, dass mit so etwas wie Peek() würde Ihnen helfen, vermeiden Sie diese magischen zahlen?
  • fertig stackoverflow.com/a/13583279/659190
  • sehen EDIT2
  • Das bedeutet, dass, wenn es einen permanenten Fehler, du wirst niemals Fortschritte Vergangenheit Element. Wenn es das ist, was Sie wollen, Sie können einfach verwenden, unbegrenzte Anzahl von Wiederholungen, Sie brauchen nicht Peek() für, die.

InformationsquelleAutor sll | 2012-11-27
Schreibe einen Kommentar