Warum beendet eine StackOverflowException in einer untergeordneten AppDomain die übergeordnete AppDomain?

8

Ich hatte den Eindruck, dass AppDomains voneinander isoliert sind. Es scheint, dass dies im Fall einer StackOverException nicht der Fall ist.

Um das Problem zu demonstrieren, habe ich eine einfache Konsolenanwendung erstellt, deren einziger Zweck es ist, eine neue AppDomain zu erstellen, in die ich eine sehr einfache Assembly lade und eine ihrer Methoden aufrufen kann. Diese Methode löst eine StackOverflowException aus. Dies führt dazu, dass meine Konsolenanwendung unbemerkt beendet wird.

Mein gewünschtes Verhalten besteht darin, dass die "untergeordnete" Anwendungsdomäne bei einer solchen Ausnahme abstürzt und abbrennt, aber meine Konsolenanwendung, die in der "übergeordneten" Anwendungsdomäne ausgeführt wird, unversehrt lässt.

Ist das möglich?

UPDATE: hier ist ein Code. Keine der Ausnahmebehandlungsroutinen wird getroffen.

%Vor%     
Mike Chamberlain 22.02.2011, 12:38
quelle

2 Antworten

7

Nur der verwaltete Speicher ist zwischen AppDomains isoliert. Wenn ein Thread in einer beliebigen Anwendungsdomäne eine Ausnahme auslöst, führt dies zum Absturz der gesamten Anwendung.

Ich denke, die beste Lösung besteht darin, sicherzustellen, dass alle Ausnahmen in jedem Thread (oder Thread-Pool-Arbeitselementen) ordnungsgemäß behandelt werden.

Es gibt jedoch einen Hack, der darin besteht, diese Konfiguration in der App.Config-Datei anzuwenden:

%Vor%

Unbehandelte Ausnahmen stürzen den Prozess seit .Net 2.0 ab, aber Sie können mit diesem Trick zur alten Richtlinie zurückkehren.

Ich würde das vorsichtig zäh verwenden, da es oft am besten ist, Prozesse abstürzen zu lassen, anstatt stillschweigend zu versagen. Sie können Ablaufverfolgungen in AppDomain.UnhandledException hinzufügen, um benachrichtigt zu werden, wenn eine unbehandelte Ausnahme auftritt, und sie entsprechend zu behandeln.

BEARBEITEN

Sie haben recht mit StackOveflowException, da .Net 2.0 diese Ausnahme nicht vom Benutzercode verarbeitet werden kann. (Siehe den Abschnitt "Bemerkungen" von diese Seite in msdn ).

Es gibt eine Möglichkeit, dies zu umgehen, indem Sie einen benutzerdefinierten CLR-Host erstellen, aber das scheint eine verrückte Sache zu sein. Ich denke, Sie müssen damit leben, oder Sie können Child-Prozess statt AppDomain erstellen, wenn Sie diese Art von Fehlertoleranz wirklich brauchen.

    
Jeff Cyr 22.02.2011, 14:07
quelle
1

Ich nehme an, dass das Problem darin besteht, dass Sie eine Methode aufrufen, die eine Ausnahme in Ihrer Hauptanwendungsdomäne verursacht. Wenn Sie eine Methode in Hauptanwendungsdomäne aufrufen, ruft diese Methode die Problemmethode von untergeordneter Anwendungsdomäne auf. Die Ausnahme tritt in der untergeordneten Anwendungsdomäne auf, wird jedoch über den Aufrufstapel an Ihre aufrufende Anwendungsdomäne (Hauptanwendungsdomäne) weitergegeben. Versuchen Sie, diese Methode vollständig von untergeordneten AppDomain aufzurufen. Erstellen Sie beispielsweise einen Thread in der untergeordneten Anwendungsdomäne, sodass dieser Thread die Problemmethode aufrufen sollte.

    
Dmitry Lobanov 22.02.2011 13:00
quelle

Tags und Links