2009-07-21 13 views

Odpowiedz

7

Co sądzisz o obsłudze wyjątków podczas wykonywania wątku?

Powinieneś obsługiwać wyjątki, ilekroć jest to możliwe i kiedy tylko spodziewasz się wyjątków. Wyjaśnienie: Całkowicie zgadzam się z Johnem, że nie powinno się zajmować wyjątkami wszędzie - tylko tam, gdzie można coś z nimi zrobić. Jednak nigdy nie należy dopuszczać wyjątków w wątku, ponieważ spowoduje to poważne problemy. Masz program obsługi wyjątków root i niech twoja wątek zginie z wdziękiem (po zarejestrowaniu problemu itp.)

Co się stanie, jeśli wątek zostanie wrzucony do bloku catch w klauzuli "catch-up"?

Czy miałeś na myśli: Co zrobić, jeśli wyjątek zostanie rzucony w bloku catch? Cóż, następnie nie jest obsługiwane przez bieżący blok try-catch. Najlepiej nie umieszczać zbyt wiele przetwarzania w bloku catch, aby uniknąć tej sytuacji tak bardzo, jak to możliwe.

A co stanie się z nicią, jeśli wątek jest nieobsługiwany?

Czy miałeś na myśli: Co stanie się z wątkiem, jeśli wyjątek nie zostanie usunięty? To umiera.

I jak Ben wymienić:

przechwycony wyjątek w wątku wyzwala UnhandledException w AppDomain przez wątku. Można oglądać na tych przez dodanie obsługi zdarzeń:

AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; 
+0

dzięki za złapanie literówki – weilin8

+0

@rein: nie tylko wątek umiera; przerywa cały proces. –

+0

Polecam jakoś włączyć informacje zawarte w odpowiedzi Bena do twojego ostatniego oświadczenia. Wątek zginie, jeśli istnieje nieobsługiwany wyjątek, ale na tym się nie kończy. Wyjątek będzie propagował łańcuch do AppDomain i zabije twoją aplikację, jeśli nie masz do tego innego programu obsługi. – jasonh

4

przechwycony wyjątek w wątku wyzwala UnhandledException w AppDomain wątku jest. Można oglądać na nich przez dodanie obsługi zdarzeń:

AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

+0

Pamiętaj jednak, że nie możesz "obsłużyć" wyjątku w tradycyjnym sensie. Po wykonaniu tej procedury obsługi zdarzenia AppDomain prawdopodobnie zginie. To wykorzystanie tego zdarzenia jest głównie po to, aby móc rejestrować informacje o wyjątku lub podobnych działaniach. –

+0

Tak - powinienem był o tym wspomnieć. –

7

muszę się nie zgodzić z ren, albo przynajmniej z tego, co brzmi jak miał na myśli.

Obsługuj tylko wyjątki, jeśli faktycznie możesz obsługiwać im. Tylko jeśli możesz zrobić coś, co poszło nie tak, lub dodać informacje. Nie obchodź się z nimi tylko dlatego, że możesz.

try { 
    // .. 
} catch (Exception ex) { 
    Console.WriteLine(ex.Message); 
} 

Powyższe jest bardzo złe. Po pierwsze, nie wyświetlasz całego wyjątku, lecz tylko komunikat. Po drugie, pozwalasz, aby wszystko było kontynuowane, i nie wiesz, w jakim stanie znajduje się proces.

+0

Uzgodnione. Nie chciałem sugerować, że powinny być try-catch bloki wokół każdego kawałka kodu. Dzięki za złapanie tego. – rein

+0

Całkowicie się zgadzam. Ton odpowiedzi wodza (choć wyjaśnił, że nie miał na myśli tego) może być dla początkujących, że pisanie bloków try-catch jest dobrą rzeczą. Powiedziałbym, spróbuj napisać kod bezpieczny w wyjątkach, z możliwie najmniejszymi blokami try-catch; i dopiero wtedy zacznijcie dbać o wyjątki, którymi można się posługiwać w bardzo konkretnych przypadkach. Tylko na najwyższym poziomie aplikacji (i prawdopodobnie głównych granic warstw aplikacji), dbasz o wychwycenie wszystkich wyjątków (w celu raportowania i zręcznego zezwalania na zanikanie aplikacji) – jeroenh

1

Nieobsługiwane wyjątki w wątku powodują, że proces umiera i umiera z niepomocnym komunikatem w dzienniku zdarzeń.

Obsługa wyjątków najwyższego poziomu w każdym wątku, który jest logiem (i może ponownie rzutem) jest dobrą praktyką, tak jak podczas instalowania wyjątku appdomain, jak wspominają inne odpowiedzi.

0

Jeśli sądzisz, że poradzisz sobie z wyjątkiem, powinieneś go złapać. Wszystkie inne wyjątki, z którymi nie można sobie poradzić, powinny pojawiać się na powierzchni stosu, jeśli po drodze nie znajdzie się odpowiedni przewodnik, pozwolą nić umrzeć.

Nie powinieneś pisać żadnego kodu w bloku catch, który mógłby rzucić inny wyjątek, ale jeśli potrzebujesz, możesz zagnieździć inny blok catch catch wokół niego.

0

Mechanizmy wyjątku .net zasadniczo nie zapewniają żadnego dobrego sposobu na obsługę wyjątku podczas wykonywania bloku catch lub podczas wykonywania bloku "finally", podczas gdy inny wyjątek oczekuje. Właściwa obsługa wymagałaby, aby .net obsłużył typ wyjątku złożonego, który mógłby zostać przechwycony przez bloki "catch" dla któregokolwiek z jego składników, ale który byłby automatycznie ponownie wyrzucony do stosu wywołań, dopóki wszystkie części składowe nie zostałyby rozpatrzone. Niestety .net nie zapewnia żadnych takich złożonych typów wyjątków; podczas gdy można zdefiniować i używać typów niestandardowych w taki sposób, aby uzyskać taką semantykę, kod do ich używania byłby raczej brzydki i nie integrują się one dobrze z wyjątkami, które mógłby wyrzucić inny kod.

W związku z tym mamy do czynienia z wyborem: stłumić nowy wyjątek i pozwolić staremu propagować, pozwolić nowemu propagować i tracić stary, lub tworzyć złożony obiekt wyjątku, który może być obsługiwany tylko przez kod, który wie żeby go szukać. Żaden z nich nie jest szczególnie przyjemnym wyborem. Który z nich jest najlepszy, będzie zależeć od zrozumienia warunków, jakie reprezentują różne typy wyjątków i jaki kod wywoławczy będzie się z nimi oczekiwał.

Powiązane problemy