Ogólnie tak, w końcu będzie działać.
W przypadku następujących trzech scenariuszy w końcu ZAWSZE uruchomi się:
- Nie występują wyjątki
- Wyjątki synchroniczne (wyjątki występujące w normalnym przebiegu programu).
Obejmuje to wyjątki zgodne z CLS, które pochodzą z System.Exception i wyjątki niezgodne z CLS, które nie pochodzą z System.Exception. Wyjątki niezgodne z CLS są automatycznie pakowane przez wyjątek RuntimeWrappedException. C # nie może zgłaszać wyjątków skarg innych niż CLS, ale języki takie jak C ++ mogą. C # może wywoływać kod napisany w języku, który może zgłaszać wyjątki niezgodne z CLS.
- Asynchroniczny wyjątek ThreadAbortException
Począwszy od platformy .NET 2.0 wyjątek ThreadAbortException nie będzie już uniemożliwiać ostatecznego uruchomienia. ThreadAbortException jest teraz podnoszony przed lub po końcu. Ostatecznie zawsze będzie działać i nie zostanie przerwane przerwaniem wątku, o ile próba została faktycznie podjęta przed przerwaniem wątku.
Następujący scenariusz ostatecznie nie uruchomi się:
Asynchroniczny wyjątek StackOverflowException.
Od wersji .NET 2.0 przepełnienie stosu spowoduje zakończenie procesu. Ostatecznie nie zostanie uruchomione, chyba że zastosowane zostanie dalsze ograniczenie, aby ostatecznie utworzyć CER (region ograniczonego wykonywania). CER nie powinny być używane w ogólnym kodzie użytkownika. Powinny być używane tylko tam, gdzie krytyczne jest, aby zawsze działał kod czyszczący - po tym wszystkim proces i tak zostanie zamknięty z powodu przepełnienia stosu, a zatem wszystkie zarządzane obiekty będą domyślnie czyszczone. Dlatego jedynym miejscem, w którym powinna być odpowiednia CER, są zasoby przydzielone poza procesem, np. Niezarządzane uchwyty.
Zazwyczaj niezarządzany kod jest pakowany przez niektóre klasy zarządzane, zanim zostanie wykorzystany przez kod użytkownika. Zarządzana klasa opakowania zwykle korzysta z SafeHandle do zawijania niezarządzanego uchwytu. SafeHandle implementuje krytyczny finalizator i metodę Release, która jest uruchamiana w CER, aby zagwarantować wykonanie kodu czyszczenia. Z tego powodu nie powinieneś widzieć CER zaśmieconych przez cały kod użytkownika.
Zatem fakt, że w końcu nie działa na StackOverflowException, nie powinien mieć wpływu na kod użytkownika, ponieważ proces i tak zostanie zakończony. Jeśli masz przypadek na krawędzi, w którym musisz wyczyścić niektóre niezarządzane zasoby, poza SafeHandle lub CriticalFinalizerObject, użyj CER w następujący sposób; ale należy pamiętać, że jest to zła praktyka - niezarządzana koncepcja powinna zostać wyodrębniona do klas zarządzanych i odpowiednich SafeHandle z założenia.
na przykład,
// 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.
}