Problems with "global" exception handlers for unhandled exceptions in multithreaded WPF
I have a program that, among other things, needs to be able to refresh the contents of a directory when the user tells it to. The actual task doesn't really matter, but this is the simplest way of causing this problem to occur that I know of. If I tell it to open a directory that doesn't exist, I get the "unhandled exception" dialog in VS with a stack trace of, from outer to inner:
[External code]
Textbox PreviewKeyUp event
[External code]
ClassA's path property being set
ClassA's internal path update function being called
A call to the INotifyPropertyChanged event
[External code]
A call to the getter for ClassB's list of children
A call to ClassB's internal directory list function
And then it fails inside this internal function. I have the following in my App.xaml.cs:
private void Application_Startup(object sender, StartupEventArgs e)
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.Current.Dispatcher.UnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(Dispatcher_UnhandledException);
}
But neither of their exception handlers are being called. If I run this program from outside VS, I don't get notified of an exception at all, it just breaks because of the invalid input. And yes, the Application_Startup event is being called. How can I properly "trap" this exception so I can provide a friendly error message and kill the program?
Oh, and if I put a try/catch anywhere up the call stack past an External Code call, it doesn't catch it, either.
[edit]
After some searching, I'm pretty sure this is a side effect of WPF's binding system. Because the DirectoryInfo is being created successfully (even on a directory that doesn't exist), the error doesn't occur until a binding goes to retrieve the value - and WPF eats binding exceptions. I'm leaving this open in case anyone has any further开发者_Python百科 ideas, but I think I the best I can do is abandon lazy-loading if I think it can lead to exceptions, at least until the application is more proven.
Try attaching to the apps DispatcherUnhandledException
.
private void Application_Startup(object sender, StartupEventArgs e)
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.Current.Dispatcher.UnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(Dispatcher_UnhandledException);
this.DispatcherUnhandledException += ...
}
精彩评论