2010-10-11 3 views
8

Mam problem z źle zachowaną biblioteką, która zgłasza wyjątek w finalizatorze, co oczywiście powoduje awarię aplikacji.Czy mogę wyłączyć nieprzechwycony wyjątek w innym AppDomain od wyłączenia aplikacji?

Aby tego uniknąć, próbowałem załadować bibliotekę we własnej domenie AppDomain, ale wyjątek nadal jest wyświetlany na powierzchni i powoduje awarię aplikacji.

Zgodnie z dokumentacją MSDN, rejestracja na AppDomain.UnhandledException nie zapobiega powstawaniu bulgoczącego wyjątku, ale jestem zaskoczony, że nie ma innego sposobu na złapanie takiego wyjątku w "sub AppDomain".

W jaki sposób wtyczki obsługujące wtyczki lub aplikacje używające domeny AppDomains do piaskowania potencjalnie szkodliwego kodu robią, aby zatrzymać nieobsługiwane wyjątki? Czy to w ogóle możliwe?

Uwaga: Mam już inne obejście problemu, opisane here. Zły finalizator znajduje się na długo żyjącym obiekcie, który wydaje się być gromadzony tylko podczas zamykania, więc wystarczy ukryć ten "fałszywy" błąd od użytkownika. Mimo to uważam, że to obejście jest kruchy, ponieważ albo ukryje inne, prawdziwe błędy, albo ryzykuje wysadzenie mojej aplikacji, jeśli obiekt zostanie zebrany wcześniej.

+0

Dlaczego nie można złapać wyjątku? – rerun

+0

Wyjątek jest zgłaszany w Finalizerze, który działa we własnym wątku zarządzanym przez CLR, więc nie mogę umieścić obsługi wyjątku w wątku. Jest to również biblioteka "starszego, nieprzydatnego i ważnego komponentu bez kodu źródłowego" ... –

Odpowiedz

4

Aplikacja AppDomain jest przyjemna, ponieważ można porzucić stan programu, ale wciąż masz problem z tym, że wątek jest martwy. To, że dzieje się to w wątku finalizatora, jest fatalne, CLR przerwie proces bez regresu.

Jedyną "poprawką" jest uruchomienie tego komponentu we własnym procesie. Możesz strzelić w głowę za pomocą Process.Kill(), aby zapobiec uruchomieniu wątku finalizatora przy wyjściu z procesu. Użyj jednego z mechanizmów komunikacji międzyprocesowej obsługiwanych przez .NET, aby z nim porozmawiać. Gniazdo o nazwie potok, Remoting lub WCF. Powodzenia z tym.

+0

Dzięki za odpowiedź, pomyślałem, że jest lepsza izolacja między AppDomains, szkoda. Myślę, że pozostaniemy z obecnym obejściem i wyizolujemy bibliotekę w jej własnym procesie w następnej wersji. –

0

Właściwie z powrotem w .NET 1.0/1.1, zachowywał się tak, jak potrzebujesz. można jeszcze powrócić do tego problemu poprzez dodanie ten wiersz do pliku konfiguracyjnego aplikacji wewnątrz węzła „czas pracy”:

<runtime> 
    <legacyUnhandledExceptionPolicy enabled="1"/> 
</runtime> 

To zapobiegnie nieobsługiwany wyjątek w innym wątku od zakończenia całego procesu.

+2

Wiem o tej opcji, ale to ukrywałoby wyjątki od każdej nici, co zdecydowanie nie jest tym, czego chcę. –