ThreadOption.BackgroundThread missing exceptions

Topics: Prism v2 - WPF 3.5
Dec 17, 2010 at 8:00 PM

We are subscribing for events with the ThreadOption set to ThreadOptions.BackgroundThread. The delegate that is being called is throwing an exception and it is not being caught anywhere. I don't get any of my error dialogs, the app doesn't crash, etc.... When I switch the thread option to ThreadOptions.UIThread, the exception gets picked up in my applications DispatcherUnhandledException event handler. Can anyone provide any insight into what I am missing here? Why is the application not in some way catching the exception and if it is not being caught, why is the application not exiting?

Thanks

Developer
Dec 17, 2010 at 8:12 PM
Edited Dec 17, 2010 at 8:12 PM

Hi,

You might find the following article from MSDN useful.

From the article:

"If an exception is not handled on either a background user interface (UI) thread (a thread with its own Dispatcher) or a background worker thread (a thread without a Dispatcher), the exception is not forwarded to the main UI thread. Consequently, DispatcherUnhandledException is not raised. In these circumstances, you will need to write code to do the following:

 

  1. Handle exceptions on the background thread.

  2. Dispatch those exceptions to the main UI thread.

  3. Rethrow them on the main UI thread without handling them to allow DispatcherUnhandledException to be raised.

For more information, see the Threading Model overview."

As this is not strictly related to Prism, you might find better support in the WPF Forum.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

 

Dec 17, 2010 at 8:37 PM

The reason I posted this here is because I created a sample app that does what prism does and queues a work item to the thread pool. Within the action I throw an exception. I do not try and catch this exception anywhere and the AppDomain's UnhandledException ends up picking up the exception and displaying some dialog (I coded this handler). In the prism case this does not happen so I was wondering if there was something within Prism that is preventing the AppDomain from catching this exception and instead just ignoring it somewhere. Or some other subtlety that I am not aware of.

Thanks

Developer
Dec 20, 2010 at 6:40 PM

Hi,

We haven't been able to reproduce your scenario. It could be helpful if you could provide a repro sample so that we can help you troubleshoot your issue.

Thanks.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Dec 21, 2010 at 6:19 PM

Thanks, I will see if I can abstract the logic out of our application into a sample application.

Dec 21, 2010 at 6:44 PM
Edited Dec 22, 2010 at 1:11 PM

In addition I found this on stackoverflow.com which seems to be the same problem. It was not resolved. My handler is being run in the background (I subscribe with ThreadOption.BackgroundThread). Subscribing on the UI or Publisher thread is not an option.

http://stackoverflow.com/questions/2314228

 

The exception is showing up in the output window so something, somewhere is picking it up and outputting it. I see this in the console: A first chance exception of type 'System.Exception' occurred in Wmc.Gtseq.TradingPad.Block.OrderDetail.dll

Dec 22, 2010 at 1:13 PM

Hi,

I have a sample application that shows this problem. It does appear to be a problem within Prism. How do I attach it to this thread?

Thanks

 

Developer
Dec 22, 2010 at 4:40 PM

Hi,

You could upload this to SkyDrive, or any other storage site you'd like to, and post the link here.

Thanks.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Dec 22, 2010 at 5:59 PM

Here is the link to the solution:

http://cid-b95fbb6b930c995f.office.live.com/browse.aspx/PrismExceptionIssue?uc=1

Developer
Dec 22, 2010 at 7:12 PM

Hi Ben,

You could try configuring Visual Studio to break on the exceptions of the type you're throwing (in this case, System.Exception).

You might find this article useful to achieve that configuration.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Dec 22, 2010 at 7:24 PM
Edited Dec 23, 2010 at 12:38 PM

Thanks for your help but I don't think this helps me as I am already configured this way. I run with exceptions turned on all the time so I can break right at the point of any exception. My code does stop here but that isn't the problem. The problem is that the resulting exception seems to vanish after this point. There is no code in my sample app, aside from the unhandled exception handler at the app level, that is handling this exception I am throwing. If I am not handling and suppressing it then who is? Since I don't have a try/catch in the event handler I would expect the unhandled exception handler at the app level to catch it or even have the app vaporize on me. Neither of which happen. When I publish an event to the background and an exception is thrown from the handler, it never materializes anywhere. I expect it to . When I switch the publish call to run on the UI thread I see that the dispatcher unhandled exception picks it up. So in the background case it is the unhandled exception handler at the app level that should be getting it based on this.  If you turn off exceptions completely or run in release mode and press the center button in the sample application nothing happens. The exception we are throwing doesn't go anywhere. Where did the exception go?

Thanks,

Ben

Dec 23, 2010 at 6:40 PM

I think I figured out what is broken with the prism code in v2.2. In the BackgroundEventSubscription class InvokeAction method it creates a BackgroundWorker and invokes async. The subscription allows us to provide the worker delegate but does not provide for a worker completed delegate where we could pick up the error/exception and react accordingly. Does this make sense?

Developer
Dec 23, 2010 at 6:53 PM
Edited Dec 23, 2010 at 6:54 PM

Hi,

We've been spiking with your sample solution and reached the same conclusion. You could extend the CompositePresentationEvent to allow a subscription that can notify exceptions that could happen on the background thread, by providing an event handler for the RunWorkerCompleted event.

The code for the aforementioned event handler could look like this:

        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if(e.Error!=null)
            {
                throw e.Error;
            }
        }

Additionally, it could be helpful to remark that in Prism v4, the behavior for the InvokeAction method of the BackgroundEventSubscription class has been modified. The current InvokeAction method queues the delegate you're pointing to to the thread pool. To illustrate what I'm saying, here's the code for the method:

        public override void InvokeAction(Action<TPayload> action, TPayload argument)
{
ThreadPool.QueueUserWorkItem( (o) => action(argument) );
}

Using this mechanism, we've found that exceptions thrown on the delegate provided to a background event subscription are forwarded accordingly.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Dec 23, 2010 at 6:57 PM

Yes thank you very much for confirming. I was going to do something similar to what you describe until we get some time to upgrade to the newer version. Thanks for your help with this matter.