Generell ja, das läuft endlich.
Für die folgenden drei Szenarien wird das endlich IMMER ausgeführt:
- Es treten keine Ausnahmen auf
- Synchrone Ausnahmen (Ausnahmen, die im normalen Programmablauf auftreten).
Dies umfasst CLS-kompatible Ausnahmen, die von System.Exception abgeleitet sind, und nicht CLS-kompatible Ausnahmen, die nicht von System.Exception abgeleitet sind. Nicht CLS-kompatible Ausnahmen werden automatisch von der RuntimeWrappedException umbrochen. C # kann keine Nicht-CLS-Beschwerdeausnahmen auslösen, Sprachen wie C ++ jedoch. C # ruft möglicherweise Code auf, der in einer Sprache geschrieben ist, die nicht CLS-kompatible Ausnahmen auslösen kann.
- Asynchrone ThreadAbortException
Ab .NET 2.0 verhindert eine ThreadAbortException nicht mehr, dass eine endgültige Ausführung ausgeführt wird. ThreadAbortException wird jetzt vor oder nach dem endgültigen angehoben. Das endgültige wird immer ausgeführt und nicht durch einen Thread-Abbruch unterbrochen, solange der Versuch tatsächlich eingegeben wurde, bevor der Thread-Abbruch erfolgte.
Das folgende Szenario wird schließlich nicht ausgeführt:
Asynchrone StackOverflowException.
Ab .NET 2.0 wird der Prozess durch einen Stapelüberlauf beendet. Das finally wird nicht ausgeführt, es sei denn, eine weitere Einschränkung wird angewendet, um das finally zu einer CER (Constrained Execution Region) zu machen. CERs sollten nicht im allgemeinen Benutzercode verwendet werden. Sie sollten nur verwendet werden, wenn es wichtig ist, dass der Bereinigungscode immer ausgeführt wird - nachdem der gesamte Prozess ohnehin beim Stapelüberlauf heruntergefahren wurde und alle verwalteten Objekte daher standardmäßig bereinigt werden. Daher sollte eine CER nur für Ressourcen relevant sein, die außerhalb des Prozesses zugewiesen werden, z. B. nicht verwaltete Handles.
In der Regel wird nicht verwalteter Code von einer verwalteten Klasse umbrochen, bevor er vom Benutzercode verwendet wird. Die verwaltete Wrapper-Klasse verwendet normalerweise ein SafeHandle, um das nicht verwaltete Handle zu verpacken. Der SafeHandle implementiert einen kritischen Finalizer und eine Release-Methode, die in einer CER ausgeführt wird, um die Ausführung des Bereinigungscodes zu gewährleisten. Aus diesem Grund sollten Sie keine CERs im gesamten Benutzercode sehen.
Die Tatsache, dass die Funktion schließlich nicht auf StackOverflowException ausgeführt wird, sollte sich nicht auf den Benutzercode auswirken, da der Prozess ohnehin beendet wird. Wenn Sie einen Randfall haben, in dem Sie eine nicht verwaltete Ressource außerhalb eines SafeHandle- oder CriticalFinalizerObject bereinigen müssen, verwenden Sie eine CER wie folgt. Beachten Sie jedoch, dass dies eine schlechte Praxis ist. Das nicht verwaltete Konzept sollte von Natur aus in eine verwaltete Klasse und geeignete SafeHandle (s) abstrahiert werden.
z.B,
// No code can appear after this line, before the try
RuntimeHelpers.PrepareConstrainedRegions();
try
{
// This is *NOT* a CER
}
finally
{
// This is a CER; guaranteed to run, if the try was entered,
// even if a StackOverflowException occurs.
}