Finalisten werden immer von .net framework aufgerufen, sodass die Sequenz außer Kontrolle geraten könnte. und selbst wenn der Konstruktor fehlgeschlagen ist, kann der Destruktor weiterhin ausgelöst werden.
Dies könnte zu Problemen führen, wenn solche Finalizer-Ausnahmen von einer Bibliothek eines Drittanbieters kommen: Ich kann keinen Weg finden, damit umzugehen!
Zum Beispiel wird im folgenden Code, obwohl der Konstruktor der Klasse A immer eine Ausnahme auslöst und fehlschlägt, der Finalizer von A vom .NET-Framework ausgelöst, und auch ~ B () wird aufgerufen, da A eine Eigenschaft vom B-Typ hat.
%Vor%Wenn das mein Code ist, ist es ein bisschen einfacher - Ich kann Try-Catch in Finalizern verwenden, zumindest kann ich etwas Logging machen - Ich kann zulassen, dass die Ausnahme das Programm zum Absturz bringt, um den Fehler so schnell wie möglich zu entdecken - oder wenn ich die Ausnahme "tolerieren" möchte, kann ich einen try-catch haben, um die Ausnahme zu unterdrücken, und einen graziösen Ausgang haben.
Aber wenn A und B Klassen aus einer 3rd-Party-Bibliothek sind, kann ich nichts tun! Ich kann nicht kontrollieren, dass die Ausnahme passiert, ich kann sie nicht fangen, also kann ich sie nicht protokollieren oder unterdrücken!
Was kann ich tun?
Klingt wie das 3rd Party Utility schlecht geschrieben ist. :)
Haben Sie versucht, es mithilfe von AppDomain.UnhandledException einzufangen?
>Vielleicht möchten Sie einen globalen Ausnahmehandler für Ihre Anwendung in Betracht ziehen. Sie haben nicht angegeben, ob Sie ASP.NET, WinForm, MVC usw. ausführen, aber hier ist eine für eine Konsolenanwendung:
.NET Global-Ausnahmehandler in der Konsolenanwendung
>In ASP.NET können Sie die Datei Global.asax verwenden, um nicht behandelte Ausnahmen abzufangen.
Wenn Sie GC.Collect () in Ihrer Anwendung immer aufrufen, könnten Sie versuchen, das auch in einen try-catch-Block einzufügen.
Nur ein paar Ideen zu berücksichtigen.
Sie können GC.SuppressFinalizer (objA) und GC.KeepAlive (objA) was den Müll verhindert collector ruft das finalize für dieses Objekt auf, und wenn% ce_de% verwendet wird, wird KeepAlive
nicht abgeschlossen, weil objB
"was am Leben ist" immer noch eine Referenz davon hat. Sie sollten jedoch auf Speicherlecks achten, wenn Sie vergessen haben, objA
ordnungsgemäß zu finalisieren oder zu löschen.
Aber nehmen wir an, dass die objA
an einem bestimmten Punkt in einer Methode zum Beispiel eine andere objA
initialisiert hat und sie nicht richtig disponiert, Dann kann ich leider nichts dagegen tun.
Eine andere Sache, die Sie versuchen können, ist zu überprüfen, ob sich diese Bibliothek anders verhält, wenn Sie sich in objectB
mode befinden und nicht im Release
mode; zum Beispiel werfen sie vielleicht nur eine Exception im Finalizer, wenn sie im Debug-Modus aufgerufen wird. "Das ist ein Helfer für Entwickler. Wenn sie also nicht dispose oder finalize das Objekt in der richtigen Weise auslöst, wird eine Exception beim Debuggen ausgelöst":
Wenn das nicht der Fall ist, dann denke ich, dass Sie schlechte Tage mit dieser Bibliothek haben werden.