so i came across this interesting article on WPF exception handling:
http://srtsolutions.com/public/item/251263
it works by declaring DispatcherUnhandledException handler in xaml <application> node.
but what if a WPF window is launched from win forms application?
where can i declare a general exception handler?
The problem is that when WPF crashes, it brings down the whole WinForms app with it.
*Edit
what if instead of launching the WPF window directly, i launched an "Application" which than defined a start window?? is that possible/advisable?
Attach your handler to the <obj>.Dispatcher.UnhandledException event, where <obj> is any WPF control, or another DispatcherObject that is created on the same thread.
I believe the traditional "global" exception handlers for Windows Forms would apply here:
Hook the thread exception as the first line in Main:
Application.ThreadException += new ThreadExceptionEventHandler(new ThreadExceptionHandler().ApplicationThreadException);
Related
I have several projects, each of thern have UserControl to manage them. All projects are in one solution and working simultaneously. all UserControls are in TabControl. But if one project don't handle his exception, all solution fail down. How can i run each UserControl in another Thread ?
I have several classes, they are models in MVVM. All of them have ViewModel and View. Now all classes start and workig in one thread. If one of then throw exception< all app will fail down. I want taht all models working in individual thread. But all Views of taht models are together in TabControl. How i can organize this sheme?
You can't. WPF has one, and only one, user interface thread. Modifying user interface elements from a background thread won't work and will raise an exception. (EDIT: This is not entirely correct, apparently it is possible to start individual windows in their own threads.)
If you have a problem with uncaught exceptions, have a look at the Application.DispatcherUnhandledException event, which allows you to register a central exception handler for your complete WPF application. If you set e.Handled = true;
at the end of your DispatcherUnhandledException handler, exceptions will cause your application to fall back to the user interface rather than terminating the application.
More information:
WPF global exception handler
I am creating a WPF Office add in, and I would like to handle all exceptions in one place. To do this I use the following code in the constructor of my MainWindowViewModel:
Dispatcher.CurrentDispatcher.UnhandledExceptionFilter += new
DispatcherUnhandledExceptionFilterEventHandler(HandleAllException);
In my test environment I host the WPF app from a console application project, and exceptions are handled as expected. When I host the WPF app from within word however, nothing happens when exceptions are thrown. There is no notification at all that there has even been an exception, other than in the output window in visual studio. Does anyone have any suggestions as to what I might be doing wrong?
I have solved the problem by changing the way in which I launch my WPF app. I believe the problem was related to this.
I am new to WPF and have a question regarding dispatcher and Delegate.Invoke.
In a windows forms application, we can use the invoke method to make changes to UI controls from other threads. This works because invoke “executes the specified delegate on the thread that owns the control's underlying window handle” (as per msdn).
My question is:
Why doesn't Invoke work on WPF? It should be allowed to make changes to UI as the thread that owns the UI control gets to execute the delegate, but still it throws a runtime exception that “a thread is trying to modify an object that is owned by a different thread”.
How does the dispatcher manage to make changes to WPF controls while Invoke fails?
Is it possible to do cross thread programming in WPF without using dispatcher or background worker?
1) why doesn’t invoke work on wpf?
It works fine, but perhaps you're not using it correctly. I suggest you read the documentation
It should be allowed to make changes to UI as the thread that owns the UI control gets to execute the delegate, but still it throws a runtime exception that “a thread is trying to modify an object that is owned by a different thread”
Perhaps you created a UI object on a worker thread, then tried to add it to the main UI on the UI thread ? Without seeing your code, it's only a guess...
2)How does despatcher manage to make changes to wpf controls while invoke fails?
This question is not very clear, but it's probably related to the first question anyway...
3) Is it possible to do cross thread programming in wpf without using despatcher or background worker?
If you need to manipulate the UI from a worker thread, you have to use the dispatcher. BackgroundWorker also uses the dispatcher (indirectly, through the ISynchronizationContext interface) to raise events on the UI thread. There's no way around it.
I have been developing a Lync Silverlight application in Silverlight and now I am trying to shift it to WPF.
However, I am facing some thread affinity issues. For example I display the Lync client's state on my page in a textblock, and so in my code behind have wired a state changed event handler, that writes the new state into the textblock whenever the state of Lync client changes.
Now, this worked perfectly in silverlight but seemingly is not allowed in WPF.
Now my questions are:
How come it works in Silverlight bt not in WPF, even though Silverlight is supposed to be a subset of WPF?
Thread affinity is an important concept and I know we can use invoke dispatcher, but doesn't it just beat the concept of asynchronous programming in form of event handlers and callbacks?
I have a button defined in my XAML page, and the click event handler defined on it can access other UI elements, it does not suffer the problem outlined above.
But if I define a LyncClient instance in my code-behind, event handlers defined on it cannot access the UI elements. Why so, I detected no such difference between UIElements and other objects in Silverlight?
Based on above comments, I'll suggest the following "answer"...
I would guess it is more likely than not that there is some sort of different in the way that the SL API was written than that of the WPF api. That could explain the difference in the thread that is used when the API issues the callback. To verify this, you could:
Ask MS directly
Put some diagnostics code in your callback method to log the thread ID and compare that to the main thread of the application. Do this for both SL and WPF to see if they are the same or different threads.
Open the assemblies in Reflector to inspect how each API was written.
In terms of handling this specific situation, in your callback, you could:
Get the dispatcher object (different for SL than WPF) and always issue UI updates through Dispatcher.Invoke.
Use databinding and INotifyPropertyChanged to insulate the UI from the property. You could delcare a property on a ViewModel or in the code behind. Then bind the UI's textbox to that property. Databinding has some smarts in it that will automatically marshal property changes to the correct thread (in most cases anyway).
Hope that helps.
I am using a third-party Windows Forms control that performs some actions "delayed" using the Application.Idle event.
Now that we're moving our application to WPF, these actions stopped working.
I've found that the System.Windows.Forms.Application.Idle event is not raised as expected.
How can I get the Idle event to fire in a WPF application so that I can continue to use that third-party control (within a WindowsFormsHost)? It is not possible to modify the Windows Forms control.
You should read this page on MSDN which describes the message loop behavior in a WPF application. In particular it looks like the ComponentDispatcher class can be used to catch a ThreadIdle event which would roughly correspond to the Windows Forms Application.Idle event.
You could then presumably use the System.Windows.Forms.Application.RaiseIdle method to raise the Idle event as the component expects.
If you are using a WPF Application, you are actually no longer using the System.Windows.Forms.Application class to run your application, even if your application contains a Windows Forms Control.
Instead, you are using the System.Windows.Application class (different namespace).