有时,在不可重现的情况下,我的WPF应用程序会在没有任何消息的情况下崩溃。应用程序会立即关闭。
哪里是实现全局Try/Catch块的最佳位置。至少我必须实现一个消息框:“抱歉给您带来不便……”
有时,在不可重现的情况下,我的WPF应用程序会在没有任何消息的情况下崩溃。应用程序会立即关闭。
哪里是实现全局Try/Catch块的最佳位置。至少我必须实现一个消息框:“抱歉给您带来不便……”
当前回答
除上述职位外:
Application.Current.DispatcherUnhandledException
将不会捕获从主线程以外的线程抛出的异常。您必须在抛出异常的同一线程上捕获这些异常。但是如果你想在你的全局异常处理程序中处理它们,你可以把它传递给主线程:
System.Threading.Thread t = new System.Threading.Thread(() =>
{
try
{
...
//this exception will not be catched by
//Application.DispatcherUnhandledException
throw new Exception("huh..");
...
}
catch (Exception ex)
{
//But we can handle it in the throwing thread
//and pass it to the main thread wehre Application.
//DispatcherUnhandledException can handle it
System.Windows.Application.Current.Dispatcher.Invoke(
System.Windows.Threading.DispatcherPriority.Normal,
new Action<Exception>((exc) =>
{
throw new Exception("Exception from another Thread", exc);
}), ex);
}
});
其他回答
Application.Dispatcher.UnhandledException的一个快速代码示例:
public App() {
this.Dispatcher.UnhandledException += OnDispatcherUnhandledException;
}
void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) {
string errorMessage = string.Format("An unhandled exception occurred: {0}", e.Exception.Message);
MessageBox.Show(errorMessage, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
// OR whatever you want like logging etc. MessageBox it's just example
// for quick debugging etc.
e.Handled = true;
}
我在App.xaml.cs中添加了这段代码
最好的答案可能是https://stackoverflow.com/a/1472562/601990。
下面是一些演示如何使用它的代码:
App.xaml.cs
public sealed partial class App
{
protected override void OnStartup(StartupEventArgs e)
{
// setting up the Dependency Injection container
var resolver = ResolverFactory.Get();
// getting the ILogger or ILog interface
var logger = resolver.Resolve<ILogger>();
RegisterGlobalExceptionHandling(logger);
// Bootstrapping Dependency Injection
// injects ViewModel into MainWindow.xaml
// remember to remove the StartupUri attribute in App.xaml
var mainWindow = resolver.Resolve<Pages.MainWindow>();
mainWindow.Show();
}
private void RegisterGlobalExceptionHandling(ILogger log)
{
// this is the line you really want
AppDomain.CurrentDomain.UnhandledException +=
(sender, args) => CurrentDomainOnUnhandledException(args, log);
// optional: hooking up some more handlers
// remember that you need to hook up additional handlers when
// logging from other dispatchers, shedulers, or applications
Application.Dispatcher.UnhandledException +=
(sender, args) => DispatcherOnUnhandledException(args, log);
Application.Current.DispatcherUnhandledException +=
(sender, args) => CurrentOnDispatcherUnhandledException(args, log);
TaskScheduler.UnobservedTaskException +=
(sender, args) => TaskSchedulerOnUnobservedTaskException(args, log);
}
private static void TaskSchedulerOnUnobservedTaskException(UnobservedTaskExceptionEventArgs args, ILogger log)
{
log.Error(args.Exception, args.Exception.Message);
args.SetObserved();
}
private static void CurrentOnDispatcherUnhandledException(DispatcherUnhandledExceptionEventArgs args, ILogger log)
{
log.Error(args.Exception, args.Exception.Message);
// args.Handled = true;
}
private static void DispatcherOnUnhandledException(DispatcherUnhandledExceptionEventArgs args, ILogger log)
{
log.Error(args.Exception, args.Exception.Message);
// args.Handled = true;
}
private static void CurrentDomainOnUnhandledException(UnhandledExceptionEventArgs args, ILogger log)
{
var exception = args.ExceptionObject as Exception;
var terminatingMessage = args.IsTerminating ? " The application is terminating." : string.Empty;
var exceptionMessage = exception?.Message ?? "An unmanaged exception occured.";
var message = string.Concat(exceptionMessage, terminatingMessage);
log.Error(exception, message);
}
}
你可以在不同的级别捕获未处理的异常:
AppDomain. currentdomain . unhandledexception 调度员。从单个特定的UI分派器线程中UnhandledException。 来自WPF应用程序的主UI调度程序线程。 TaskScheduler。每个使用任务调度器进行异步操作的AppDomain内的UnobservedTaskException。
您应该考虑需要在哪个级别捕获未处理的异常。
选择#2还是#3取决于你是否使用了多个WPF线程。这是一种非常奇特的情况,如果你不确定你是不是,那么很可能你不是。
除上述职位外:
Application.Current.DispatcherUnhandledException
将不会捕获从主线程以外的线程抛出的异常。您必须在抛出异常的同一线程上捕获这些异常。但是如果你想在你的全局异常处理程序中处理它们,你可以把它传递给主线程:
System.Threading.Thread t = new System.Threading.Thread(() =>
{
try
{
...
//this exception will not be catched by
//Application.DispatcherUnhandledException
throw new Exception("huh..");
...
}
catch (Exception ex)
{
//But we can handle it in the throwing thread
//and pass it to the main thread wehre Application.
//DispatcherUnhandledException can handle it
System.Windows.Application.Current.Dispatcher.Invoke(
System.Windows.Threading.DispatcherPriority.Normal,
new Action<Exception>((exc) =>
{
throw new Exception("Exception from another Thread", exc);
}), ex);
}
});
您可以处理AppDomain。UnhandledException事件
编辑:实际上,这个事件可能更合适:应用程序。DispatcherUnhandledException