Ich habe einen rekursiven Aufruf einer Methode, die eine Stapelüberlaufausnahme auslöst. Der erste Aufruf ist von einem Try-Catch-Block umgeben, die Ausnahme wird jedoch nicht abgefangen.
Verhält sich die Stapelüberlaufausnahme auf besondere Weise? Kann ich die Ausnahme richtig abfangen / behandeln?
Nicht sicher, ob relevant, aber zusätzliche Informationen:
Die Ausnahme wird nicht im Hauptthread ausgelöst
Das Objekt, in dem der Code die Ausnahme auslöst, wird manuell von Assembly.LoadFrom (...) geladen. CreateInstance (...)
c#
try-catch
stack-overflow
Toto
quelle
quelle
Assert.Fail
stattdessen eine. So ernst - wie gehen wir vor?Antworten:
Ab 2.0 kann eine StackOverflow-Ausnahme nur unter den folgenden Umständen abgefangen werden.
* "Gehostete Umgebung" wie in "Mein Code hostet CLR und ich konfiguriere die CLR-Optionen" und nicht "Mein Code läuft auf Shared Hosting".
quelle
Starting with 2.0 ...
Ich bin neugierig, was hindert sie daran, SO zu fangen und wie war es möglich1.1
(das haben Sie in Ihrem Kommentar erwähnt)?Der richtige Weg ist, den Überlauf zu beheben, aber ....
Sie können sich einen größeren Stapel geben: -
Mit der System.Diagnostics.StackTrace FrameCount-Eigenschaft können Sie die von Ihnen verwendeten Frames zählen und Ihre eigene Ausnahme auslösen, wenn ein Frame-Limit erreicht ist.
Sie können auch die Größe des verbleibenden Stapels berechnen und Ihre eigene Ausnahme auslösen, wenn dieser unter einen Schwellenwert fällt: -
Fang einfach den Käse. ;)
quelle
Cheese
ist alles andere als spezifisch. Ich würde gehen fürthrow new CheeseException("Gouda");
Auf der MSDN-Seite von StackOverflowException s:
quelle
Wie bereits mehrere Benutzer gesagt haben, können Sie die Ausnahme nicht abfangen. Wenn Sie jedoch Schwierigkeiten haben, herauszufinden, wo es passiert, möchten Sie Visual Studio möglicherweise so konfigurieren, dass es beim Werfen nicht funktioniert.
Dazu müssen Sie die Ausnahmeeinstellungen im Menü "Debuggen" öffnen. In älteren Versionen von Visual Studio befindet sich dies unter "Debug" - "Ausnahmen". In neueren Versionen ist es bei 'Debug' - 'Windows' - 'Ausnahmeeinstellungen'.
Wenn Sie die Einstellungen geöffnet haben, erweitern Sie 'Common Language Runtime Exceptions', erweitern Sie 'System', scrollen Sie nach unten und aktivieren Sie 'System.StackOverflowException'. Dann können Sie sich den Aufrufstapel ansehen und nach dem sich wiederholenden Muster von Anrufen suchen. Das sollte Ihnen eine Vorstellung davon geben, wo Sie suchen müssen, um den Code zu beheben, der den Stapelüberlauf verursacht.
quelle
Wie oben mehrmals erwähnt, ist es nicht möglich, eine StackOverflowException abzufangen, die vom System aufgrund eines beschädigten Prozessstatus ausgelöst wurde. Es gibt jedoch eine Möglichkeit, die Ausnahme als Ereignis zu erkennen:
Trotzdem wird Ihre Anwendung nach dem Beenden der Ereignisfunktion beendet (eine SEHR schmutzige Problemumgehung bestand darin, die App innerhalb dieses Ereignisses neu zu starten, haha, habe dies nicht getan und werde es niemals tun). Aber es ist gut genug für die Protokollierung!
quelle
Ja, der CLR 2.0-Stapelüberlauf wird als nicht wiederherstellbare Situation angesehen. Die Laufzeit hat den Prozess also immer noch heruntergefahren.
Weitere Informationen finden Sie in der Dokumentation unter http://msdn.microsoft.com/en-us/library/system.stackoverflowexception.aspx
quelle
StackOverflowException
beendet a den Prozess standardmäßig.Das kannst du nicht. Die CLR lässt Sie nicht. Ein Stapelüberlauf ist ein schwerwiegender Fehler und kann nicht behoben werden.
quelle
Sie können nicht, da die meisten Beiträge erklären, lassen Sie mich einen weiteren Bereich hinzufügen:
Auf vielen Websites finden Sie Leute, die sagen, dass die Möglichkeit, dies zu vermeiden, die Verwendung einer anderen AppDomain ist. In diesem Fall wird die Domain entladen. Das ist absolut falsch (es sei denn, Sie hosten Ihre CLR), da das Standardverhalten der CLR ein KillProcess-Ereignis auslöst und Ihre Standard-AppDomain herunterfährt.
quelle
Es ist unmöglich und aus gutem Grund (denken Sie zum einen an all diese Fänge (Ausnahme) {} herum).
Wenn Sie die Ausführung nach einem Stapelüberlauf fortsetzen möchten, führen Sie gefährlichen Code in einer anderen AppDomain aus. CLR-Richtlinien können so eingestellt werden, dass die aktuelle AppDomain bei Überlauf beendet wird, ohne dass dies Auswirkungen auf die ursprüngliche Domäne hat.
quelle