Die Wiederholung einer Funktion in C#, bis es nicht mehr löst eine Ausnahme aus
Ich habe eine Klasse, die nennt eine SOAP-Schnittstelle und ruft ein array von Daten zurück. Allerdings, wenn diese Anfrage mal aus, wirft es eine Ausnahme. Das ist gut so. Allerdings möchte ich mein Programm, um zu versuchen, um diesen Anruf wieder. Wenn es mal aus, ich möchte es zu halten, machen diesen Aufruf, bis er erfolgreich ist. Wie kann ich dies erreichen?
Beispiel:
try
{
salesOrdersArray = MagServ.salesOrderList(sessID, filter);
}
catch
{
?? What Goes Here to FORCE the above line of code to rerun until it succeeds.
}
- Erhöhen Sie den timeout, so dass es nicht die Ausnahmen?
- Sie können einfach rufen Sie die Methode erneut aus dem catch-block, ABER was passiert, wenn der service down ist für einen längeren Zeitraum? Wollen Sie die Methode rekursiv ausgeführt wird, für 24 Stunden? Ich würde empfehlen die Begrenzung auf eine festgelegte Anzahl von Wiederholungen.
- Aus allen diesen Antworten, nicht eine einzige person sagt, dass Sie fangen eine spezifische Ausnahme. Was, wenn der try-block enthält die Objekte, die sich in einem ungültigen Zustand zu erhalten, der
salesOrderList
? Erneuter Versuch wird nicht gelingen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Brauchen Sie nur loop forever:
Beachten Sie, dass Sie sollte fast sicher nicht eigentlich die Schleife für immer. Sollten Sie fast sicher haben eine maximale Anzahl von versuchen, und wahrscheinlich nur fangen bestimmten Ausnahmen. Fang alle Ausnahmen immer werden könnte, entsetzlich... Stell dir vor, wenn
salesOrderList
(unkonventionelle Methode, name, btw) wirftArgumentNullException
da hast du ja einen bug undfilter
null ist... tun Sie wirklich binden bis zu 100% der CPU-Leistung für immer?catch (SoapException)
etc. Sie können mehrere verschiedene exception-Typen in mehreren catch-Blöcken.Sleep
von angemessener Dauer, so dass es nicht zu 100% von der CPU zu warten, für einen service wieder online kommen. Ich könnte auch eine begrenzte exponentielle backoff (wie TCP), so dass Sie erholt sich schnell von kleineren Netzwerk-Störungen, aber versucht mal alle paar Minuten, wenn der service down ist für einen längeren Zeitraum.Wenn Sie nicht ändern können das timeout, das unten sollte funktionieren. salesOrdersArray sollte initialisiert werden, um
null
.Es Ihr nicht gernally eine gute idead Ausnahmen wie Ablaufsteuerung, aber dies zu tun, was Sie verlangten.
Müssen Sie den try/catch-block in eine Schleife zu konstruieren. Wenn Sie möchten, verbrauchen 100% der Prozessor-statt einem Thread.Schlaf in den catch-block, so dass jedesmal, wenn eine Ausnahme Auftritt, wird es einige Zeit darauf warten, die Befreiung der Prozessor um andere Dinge zu tun.
Könnte man auch angeben, geben Sie die Ausnahme, so dass nur die timeout-Ausnahme behandelt wird, und andere Arten von Ausnahmen-pass-through.
Beachten Sie, dass, TimeOutException sollte ersetzt werden durch den tatsächlichen Namen des Ausnahme... ich weiß nicht, ob das ist der echte name.
Einstellen der sleep-Zeit, in millisecs und die Menge der Wiederholungen in dem Fall, den ich präsentierte, 100 Wiederholungen von 1000ms ergibt sich eine maximale Wartezeit von 1 minute und 40 Sekunden, plus der Betrieb selbst.
Werde ich ein Transaktions - queue (MSMQ) zum speichern der service-Aufruf. Eine Schleife wird dequeue-Nachrichten und rufen Sie den Dienst in einem TransactionScope, wenn der Aufruf schlägt fehl, die Meldung erscheint immer noch in der Warteschlange. Ein ov erall timeout kann angegeben werden, indem eine Zeit abläuft in der Nachricht. Diese Lösung ist gut, wenn Sie wirklich wollen, eine zuverlässige Lösung, da ich vermutete, dass der Aufruf der operation ist entscheidend.
Versuchen
Verhalten Sie sich nach führen könnte, die eine endlose Schleife, wenn diese nie gelingt, obwohl...
Probieren Sie etwas wie dieses:
Edit: Wow! Great minds think alike! 🙂
Obwohl ich würde NICHT empfehlen Ihnen, dies zu tun für eine unbegrenzte Anzahl von Zeiten, könnten Sie eine separate Funktion aus, die einen Satz:
Diese läuft ewig, und ist mit Ausnahmen wie einer Schleife, die ist langsam. Gibt es eine Möglichkeit können Sie ändern Ihre Funktion, es gibt null zurück, anstatt eine Ausnahme zu werfen? Wenn Sie erwarten, dass dieser Aufruf schlägt fehl, regelmäßig, nicht mit einem try/catch-block.
Ich diesem Muster Folgen, um dieses problem zu lösen:
Versuchen immer scheint nicht eine gute Idee sein, so können Sie am Ende mit einem unendlichen Prozess. Wenn Sie denken, Sie brauchen viele versuche, um Ihr Ziel zu erreichen, setzen Sie einfach Riesen-Nummer hier.
Ich persönlich denke, seine klug, warten Sie ein paar Millisekunden oder Sekunden nach eac Versuch Thread.Sleep(1000); vor callig Send(Daten); --- Sie könnten zum Beispiel den attempNumber variable increse oder verringern Sie die Wartezeit, wenn Sie denken, es ist klug für Ihr Szenario.
throw ex;
Mach das nicht!throw ex;
stackoverflow.com/questions/178456/... stackoverflow.com/questions/22623/...throw
ing wieder. 2 - werfen Sie die BasisException
Klasse. Sie zwingen die Konsum-code in die schlechte Praxis der FangException
. Verwenden Sie eine geeignete Unterklasse, oder erstellen Sie Ihre eigenen.