2011-01-10 14 views
9
catch (ThreadAbortException) 
{ } 
catch (Exception ex) 
{ 
    TraceManager.TraceException(ex, 
           (int)ErrorCode.GENERIC_EXCEPTION, 
           ex.StackTrace + "\n" + ex.Message + "\n" + VendorUrl); 
} 

to sensu nawet miećCzy ma sens wychwycić wyjątek ThreadAbortException i nie wykonywać żadnych działań?

catch (ThreadAbortException) 
{ } 

lub woli, które powodują ThreadAbortException do połykania i utracone na zawsze?

+4

Fragment "ThreadAbortException" zostanie ponownie wyświetlony po zakończeniu obsługi. – Gabe

Odpowiedz

29

ThreadAbortException nie można złapać "całkowicie"; zostanie automatycznie ponownie wyświetlony na końcu bloku catch (zobacz stronę z połączonymi stronami MSDN) , o ile nie zostanie wywołana pierwsza nazwa:Thread.ResetAbort.

więc jedynym sensownym catch blok będzie:

catch (ThreadAbortException) 
{ 
    // possibly do something here 
    Thread.ResetAbort(); 
} 

Ale ten ma naprawdę zły zapach. Prawdopodobnie nie ma powodu, aby to zrobić, więc możesz przemyśleć swoje podejście.

Aktualizacja: Istnieje wiele pytań na SO, które zajmują się Thread.Abort:

This one ma taką samą odpowiedź jak dałem tutaj. This one ma odpowiedź, która rozszerza się na "nigdy nie dzwoń pod numer Thread.Abort, chyba że Cthulhu wzejdzie" (co stonowałem znacznie na "złym zapachu").

Istnieje również wiele innych.

+1

+1: Oznaczenie nit-pick. Można go złapać - po prostu zostanie ponownie wyrzucony. – Hogan

+0

@Hogan: zmienił się nieco; teraz znaczenie powinno być bardziej jasne. – Jon

+0

Bardzo ładna odpowiedź. Dałbym mu jeszcze +1, gdybym mógł. – Hogan

4

Wyjątku ThreadAbortException nie można złapać w ten sposób. Zostanie automatycznie ponownie wyświetlony na końcu bloku catch, chyba że zadzwonisz Thread.ResetAbort();

Posiadanie bloku catch, jak w przypadku ThreadAbortException, pozwala na automatyczne ponowne wygenerowanie bez bloku catch (Exception), który próbuje go obsłużyć.

-3

Zostanie złapany i zagubiony. Powinieneś naprawdę wychwytywać wyjątki, z którymi możesz coś zrobić lub zalogować się, a następnie ponownie rzucić (rzutem, nie wyrzucać nowego [wyjątek];).

0

Jeśli chcesz zrobić coś specyficznego dla różnych wyjątków, to od tego czasu musisz mieć oddzielne bloki catch. W przeciwnym razie można po prostu użyć połów jeden wyjątek

+3

Nie zgadzam się. Zazwyczaj lepiej jest mówić o tym, co łapiesz.Myślę, że jeśli nie wiesz, jakie rodzaje wyjątków może rzucić Twój blok "try", oznacza to, że nie złożyłeś wystarczającej ilości testów. –

+0

Zgadzam się Ilya. +1 – Nick

0

Wywołanie Thread.Abort na nitce skutecznie ustawia flagę, która spowoduje ThreadAbortException być rzucony dowolny kod czasu nie przetwarza tego wyjątku ani związane finally bloków. Złapanie wyjątku bez wywoływania Thread.ResetAbort() spowoduje, że środowisko wykonawcze wyrzuci kolejną ThreadAbortException przy następnej okazji. Takie zachowanie nie jest jednak całkowicie pozbawione sensu, ponieważ spowoduje, że wszystkie wewnętrzne bloki będą działać do końca, zanim wyjątek nie będzie widoczny przez bloki zewnętrznego filtra wyjątku. To, czy jest to dobre, zależy od zastosowania.

Powiązane problemy