2010-03-19 4 views
3

У меня есть код очистки, который я хотел бы выполнить в конце выполнения, даже если сбой приложения C# (удалить временные файлы и т. Д.). Это возможно сделать в C#?Выполнение кода при сбое приложения

Спасибо!

+1

Что вы подразумеваете под "crash"? – wtaniguchi

+0

То, что означают не-программные инженеры под этим словом: любое событие, которое заставляет приложение спускаться (необработанные исключения в любом потоке, деление на 0, нарушение прав доступа, C++ SEH, исходящие из моей рабочей DLL и т. Д.). – Warpin

ответ

0

Это зависит от того, что вы подразумеваете под «крушением». Если вы имеете в виду необработанное исключение, вы можете создать обработчик для Application.ThreadException. Если авария вызывается за пределами управляемого кода, вы ничего не можете сделать.

+0

На что я надеялся - это какая-то переопределяемая функция «Завершить», которую я могу написать, которая вызывается для необработанных исключений, нарушения прав доступа или любого другого, что может снести мое приложение. Большая часть работы выполняется с помощью C++ DLL, поэтому обработка исключений из нее тоже будет приятной. – Warpin

-3

Это то, что try {} finally {} для. Оберните весь свой код в свой метод main, который должен это сделать.

+4

Это может быть достаточно хорошо в простых сценариях, но как насчет многопоточных приложений? –

8

Это зависит от того, что вы подразумеваете под «крушением».

Если вы хотите иметь дело с любыми необработанными исключениями, которые в противном случае сбивали бы приложение, вы можете присоединить обработчик событий к событию AppDomain.UnhandledException, а затем обработать любые ошибки в обработчике событий.

Кроме того, в .Net 4.0 есть AppDomain.FirstChanceException, который вызывается до того, как будут выполнены блоки блокировки при возникновении исключения.

Возможно, однако, что может произойти реальный сбой (например, исключение выбрасывается из финализатора), что приводит к выходу фатального приложения, которое нелегко обработать, но в большинстве случаев, вероятно, будет достаточно событие AppDomain.UnhandledException.

+0

Я хотел вызвать метод перед любым сбоем. AppDomain.FirstChanceException помог мне. Благодаря! –

2

Есть несколько событий, на которые вы можете подписаться, чтобы получать уведомления об исключениях.

  • AppDomain.UnhandledException - Запущено необработанными исключениями в домене приложения.
  • Dispatcher.UnhandledException - Исправлено необработанными исключениями в потоке потока WPF.
  • Application.ThreadException - Выполнено необработанными исключениями на фоне потоков.

Кроме того, как отмечали другие, окончательный блок вокруг одной точки входа будет удален для любых исключений в основном потоке.

[Я бы не рекомендовал пытаться восстановить ваше приложение от этих обработчиков. В частности, в случае события AppDomain.UnhandledException, ваше приложение уже выходит, вы должны просто позволить ему отключиться. Используйте только эти обработчики для очистки или регистрации в последнюю минуту.]

5

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

Поэтому я предлагаю вам поместить этот код очистки в приложение startup. Попросите приложение искать файлы temp и т. Д. При запуске, прежде чем он начнет создавать нормальные временные файлы, если он их найдет, тогда он может либо удалить их, либо попытаться исправить/повторно использовать их.

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

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

1

Если важно, чтобы ваше приложение очистилось, вы можете создать приложение-монитор, который будет запускаться пользователем. Он запустит ваше основное приложение, а затем проверит его дескриптор процесса. Если ваше основное приложение выйдет из строя, его обработчик процесса будет сигнализировать, и ваше приложение-монитор сможет очистить и даже перезапустить основное приложение, если вы пожелаете. Я обычно совмещаю это с именованным мьютеком, который используется для подачи сигнала обратно на приложение-монитор, которое основное приложение хочет закрыть, чтобы оно не перезапустило его.

Смежные вопросы