2010-10-11 4 views
8

У меня возникают проблемы с плохой библиотекой, которая генерирует исключение в финализаторе, что, конечно же, приводит к сбою приложения.Могу ли я предотвратить неперехваченное исключение в другом приложении AppDomain при закрытии приложения?

Чтобы избежать этого, я попробовал загрузить библиотеку в свой собственный AppDomain, но исключение все еще пузырится на поверхности и вылетает из приложения.

Как указано в MSDN, регистрация на AppDomain.UnhandledException не мешает исключению из пузырьков, но я совершенно удивлен тем, что нет другого способа поймать такое исключение в «sub AppDomain».

Как блокировать хосты или приложения, использующие потенциально опасные коды приложений AppDomains, чтобы остановить необработанные исключения? Действительно ли это возможно?

Примечание: У меня уже есть другое обходное решение, описанное here. Плохой финализатор находится на долгоживущем объекте, который, кажется, собирается только во время выключения, поэтому достаточно скрыть эту «фиктивную» ошибку от пользователя. Тем не менее, я нахожу этот обходным хрупким, так как он либо скроет другие, реальные ошибки, либо рискует взорвать мое приложение, если объект будет собран ранее.

+0

Почему вы не можете поймать исключение – rerun

+0

Исключение выбрано в Finalizer, который выполняется в своем потоке, управляемом CLR, поэтому я не могу поместить обработчик исключений в поток. Кроме того, это библиотека «наследия, unmaintaiend и важного компонента без исходного кода» ... –

ответ

4

AppDomain хорош, так как вы можете остановить состояние программы, но у вас все еще есть проблема, что поток мертв. То, что это происходит в потоке финализатора, является фатальным, CLR прервет процесс без регресса.

Единственное «исправить» - запустить этот компонент в своем собственном процессе. Вы можете снимать его в голове с помощью Process.Kill(), чтобы предотвратить завершение потока финализатора при выходе процесса. Используйте один из механизмов взаимодействия между процессами, поддерживаемых .NET, чтобы поговорить с ним. Сокет, именованный канал, Remoting или WCF. Удачи вам.

+0

Спасибо за ответ, я подумал, что между AppDomains была хорошая изоляция. Я думаю, что мы останемся с текущим обходным решением, и изолируем библиотеку в своем собственном процессе в следующей версии. –

0

На самом деле, обратно в .NET 1.0/1.1, он вел себя так, как вам нужно. Вы все еще можете вернуться к этому поведению, просто добавив эту строку в файл конфигурации приложения, внутри узла «выполнения»:

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

Это предотвратит необработанное исключение в другом потоке от завершения всего процесса.

+2

Я знаю об этом параметре, но это будет скрывать исключения из каждого потока, что определенно не то, что я хочу. –