Сейчас обработка исключений в моем приложении организована следующим образом. Есть кастомный обработчик, который доступен во всех вью-моделях через DI. Он используется для "ожидаемых" исключений, после которых приложение может продолжить работу. Одновременно с этим у меня есть "финальный" обработчик для неизвестных исключений, после которых работу приложения следует завершить (нет гарантий, что приложение будет работать стабильно).
Точка входа в приложение выглядит примерно так:
public class Program
{
[STAThread]
public static void Main()
{
// Message Helper
var messageHelper = new MessageHelper();
// Exception Handler
var exceptionHandler = new MvvmExceptionHandler(messageHelper);
try
{
var mainViewModel = new MainViewModelBuilder()
.WithExceptionHandler(exceptionHandler)
.Build();
var mainWindow = new MainWindow
{
DataContext = mainViewModel
};
var app = new App(mainWindow)
{
MainWindow = mainWindow,
ShutdownMode = System.Windows.ShutdownMode.OnMainWindowClose
};
app.Run();
}
catch (Exception ex)
{
//MessageBox.Show("Application will be closed.", "Fatal error", MessageBoxButton.OK, MessageBoxImage.Error);
App.Current.Shutdown();
}
}
}
Собственно, у меня 3 связанных вопроса:
1) Нужно ли мне обрабатывать специфические для WPF исключения, т.е. подписываться на события следующих классов.
AppDomain.CurrentDomain.UnhandledException
Dispatcher.UnhandledException
Application.Current.DispatcherUnhandledException
TaskScheduler.UnobservedTaskException
Либо я смогу поймать все эти исключения в корневом try...catch?
2) Как правильно вывести пользователю сообщение о фатальной ошибке перед закрытием программы? Где-то читал, что использование WinAPI на этом уровне может заблокировать освобождение ресурсов.
3) Как корректно завершить работу приложения? Сейчас я делаю это через Application.Current.Shutdown(). Это универсальный вариант? Т.е. подходит ли для ошибок, который произошли за пределами UI-треда?