2012-06-14 11 views
19

Dlaczego linia nie jest "Console.WriteLine (" asdf ");" wykonany? Wszystkie pozostałe są. Czy nie powinno tak być, ponieważ nie możemy wyskoczyć z ostatecznego zakresu?Zagnieżdżanie próbne w końcu w C#

static bool Func() 
{ 
    try 
    { 
     try 
     { 
     } 
     finally 
     { 
      try 
      { 
       throw new ApplicationException(); 
      } 
      finally 
      { 
       Console.WriteLine("asd"); 
      } 

      Console.WriteLine("asdf"); 
     } 
    } 
    finally 
    { 
     Console.WriteLine("asd"); 
    } 
} 
+3

Powiązane: [Co się dzieje w języku C#, czy w końcu blok zgłasza wyjątek?] (Http://stackoverflow.com/questions/2911215) –

Odpowiedz

25

Wreszcie bloki tylko gwarancja (przynajmniej w większości gwarantują, zobaczyć z wyjątkiem MSDN poniżej), które będą wszedł w przypadku, gdy blok try zgłasza wyjątek. Jeśli wyrzucisz wyjątek w obrębie bloku, to wyjątek spowoduje, że kontrola opuści blok finally, a reszta kodu wewnątrz tego bloku finally nie zostanie wykonana.

W twoim przypadku linia, która nie jest wykonywana, występuje po wyjściu w tym samym bloku finally, więc zostaje pomijana.

Od MSDN - try-finally:

wreszcie blok jest przydatny do czyszczenia wszelkich zasobów, które są przydzielone w spróbować blok, a do uruchamiania kodu, który musi wykonać nawet jeśli wystąpi wyjątek w bloku spróbuj. Zazwyczaj oświadczenia o wreszcie bloku są wykonywane, gdy kontrola pozostawia spróbować stwierdzenie, czy przekazanie kontroli następuje w wyniku normalnego wykonywania, z wykonaniem przerwie, kontynuować, Instrukcja goto lub return lub propagacja wyjątku z oświadczenia wypróbuj.

W ramach obsługiwanego wyjątku, związany blok wreszcie jest gwarantowany, aby uruchomić . Jeśli jednak wyjątek jest nieobsługiwany, wykonanie bloku w końcu zależy od tego, w jaki sposób zostanie wywołana operacja odwijania wyjątku . To z kolei zależy od konfiguracji komputera. Aby uzyskać więcej informacji, zobacz Nieobsługiwane przetwarzanie wyjątków w środowisku CLR.

Uwaga: Unhandled Exception Processing in the CLR jest odniesienie do artykułu zamieszczonego w numerze września 2008 r MSDN Magazine. Wszystkie 2008 i starsze wydania MSDN Magazine są dostępne tylko jako pliki .chm i będą musiały zostać pobrane przed przeglądaniem.

+0

'" W końcu bloki gwarantują tylko * snip *, że zostaną wprowadzone, jeśli próba blok rzuca wyjątek "" masz na myśli, że ostatecznie bloki wchodzą tylko po wyjściu bloku try? (wykonywanie bloków catch na wyjątku) –

+1

To prawda. Starałem się wskazać, w jaki sposób radzą sobie z wyjątkami, a także fakt, że nie gwarantują one, że będą prowadzone w całości, ale że przynajmniej zostaną wprowadzone. –

+0

Zobacz artykuł [MSDN Magazine 2008 September: Nieobsługiwane przetwarzanie wyjątków w środowisku CLR] (http://download.microsoft.com/download/3/a/7/3a7fa450-1f33-41f7-9e6d-3aa95b5a6aea/MSDNMagazine2008_09en-us.chm). (aby otworzyć chm, musisz odblokować: Właściwości pliku -> Ogólne -> Odblokuj) – vladimir77

4

Wyjątki wyrzucone w ramach bloku końcowego (lub catch) anulują pozostałą część tego bloku (lub catch).

5

Ponieważ wyjątek jest wrzucany do tego ostatniego bloku, więc powoduje to, że kontrola wypada na końcowy blok końcowy. Tak więc "WriteFine" asdf nie jest nigdy wykonywana.

3

Błąd występuje wewnątrz bloku 3 try, co powoduje, że jego odpowiednik zostanie ostatecznie wykonany. Powoduje to jednak, że błąd z prądu w końcu zostanie przechwycony przez oryginalny blok try-finally.

1

bo trzeba rzucać w bloku try i będzie wykonywał wreszcie blokować z Console.WriteLine("asd"); i wyjściem na zewnętrzny try catch

16

Myślę, że najlepszym sposobem to można odpowiedzieć jest za pomocą kodu i stąd następujący obraz enter image description here

+4

+ 1 za niesamowite zdjęcie ... mówi tysiąc słów. –

+0

Myślę, że został złapany przez najsilniejszy blok try, w końcu niczego nie łapie. –

0

Kiedy użyłem bloków try-finally na kod rozmieszczonych na różnych platormach hosta, stwierdziłem, że: , gdy nie zgłaszano żadnych wyjątków w bloku try.

niektóre platformy Windows zawsze wykonywały blok finally i niektóre platformy nigdy nie wykonały bloku finally.

Mój blok zawierał instrukcje zamknięcia dziennika błędów, a niepowodzenie wykonania bloku finally zawsze wywoływało inny wyjątek przy wyjściu, pozostawiając jedynie dostępną informację cryptric, aby dowiedzieć się, co spowodowało błąd. Dla mojej aplikacji, próby w końcu bloków były więcej kłopotów niż były warte.

Powiązane problemy