2010-10-11 4 views
8

Ich habe Probleme mit einer fehlerhaften Bibliothek, die eine Ausnahme in einem Finalizer auslöst, was natürlich die Anwendung stürzt.Kann ich verhindern, dass eine nicht abgefangene Ausnahme in einer anderen AppDomain die Anwendung herunterfährt?

Um dies zu vermeiden, habe ich versucht, die Bibliothek in einer eigenen AppDomain zu laden, aber die Ausnahme sprudelt immer noch zur Oberfläche und stürzt die Anwendung ab.

Wie auf MSDN dokumentiert, verhindert die Registrierung auf AppDomain.UnhandledException nicht verhindern, dass die Ausnahme sprudelt, aber ich bin ziemlich überrascht, dass es keine andere Möglichkeit gibt, eine solche Ausnahme in einer "Sub-AppDomain" zu fangen.

Wie können Plug-in-Hosts oder Anwendungen, die Anwendungsdomänen zum Sandboxing von potenziell schädlichem Code verwenden, unbehandelte Ausnahmen stoppen? Ist das tatsächlich möglich?

Hinweis: Ich habe bereits eine andere Problemumgehung, die eine beschrieben here. Der schlechte Finalizer befindet sich auf einem langlebigen Objekt, das anscheinend nur während des Herunterfahrens erfasst wird. Es reicht also aus, diesen "falschen" Fehler vor dem Benutzer zu verbergen. Dennoch finde ich diese Problemumgehung spröde, da sie entweder andere, echte Fehler verdeckt, oder das Risiko birgt, dass meine Anwendung in die Luft geht, wenn das Objekt früher erfasst wird.

+0

Warum können Sie die Ausnahme nicht abfangen – rerun

+0

Die Ausnahme wird in einem Finalizer ausgelöst, die in ihrem eigenen Thread von der CLR verwaltet ausgeführt wird, so kann ich nicht einen Ausnahmehandler auf den Thread setzen. Auch dies ist eine Bibliothek der "Legacy, unmaintaiend und wichtige Komponente ohne Quellcode verfügbar" Art ... –

Antwort

4

Eine AppDomain ist nett, da Sie den Programmstatus ablegen können, aber Sie haben immer noch das Problem, dass der Thread tot ist. Dass dies beim Finalizer-Thread passiert, ist fatal. Die CLR wird den Prozess ohne Rückgriff abbrechen.

Der einzige "Fix" ist, diese Komponente in einem eigenen Prozess auszuführen. Sie können mit Process.Kill() in den Kopf schießen, um zu verhindern, dass der Finalizer-Thread beim Beenden des Prozesses ausgeführt wird. Verwenden Sie einen der Interprozess-Kommunikationsmechanismen, die von .NET unterstützt werden, um mit ihm zu kommunizieren. Ein Socket, Named Pipe, Remoting oder WCF. Viel Glück damit.

+0

Danke für die Antwort, ich dachte, es gab eine bessere Isolierung zwischen AppDomains, schade. Ich denke, wir bleiben vorerst bei der aktuellen Problemumgehung und isolieren die Bibliothek in der nächsten Version in ihrem eigenen Prozess. –

0

Eigentlich zurück in .NET 1.0/1.1 verhielt es sich wie Sie brauchen. Sie können immer noch auf dieses Verhalten zurückkehren, indem Sie einfach diese Zeile in Ihre Anwendungskonfigurationsdatei hinzufügen, in der „Laufzeit“ Knoten:

<runtime> 
    <legacyUnhandledExceptionPolicy enabled="1"/> 
</runtime> 

Dies wird eine nicht behandelte Ausnahme in einem anderen Thread verhindern, dass der gesamte Prozess beendet wird.

+2

Ich weiß über diese Option, aber das würde Ausnahmen von jedem Thread verbergen, was definitiv nicht das ist, was ich will. –