.NET 4.0 Tasks: Rotrow exception for UI thread in Task.ContinueWith

I have a WPF application where I make a long WCF call using System.Threading.Tasks. I will catch the unhandled exceptions by adding a handler to Application.Current.DispatcherUnhandledException.

I create a task where the ContinueWith function is executed in the user interface thread using the following code:

var task = new Task<T>(func).ContinueWith(t => { if (t.IsFaulted) { throw t.Exception.GetBaseException(); } else { // Show t.Result on UI } }, TaskScheduler.FromCurrentSynchronizationContext()); 

When an exception occurs in a task, I would like to rebuild the exception so that the DispatcherUnhandledException handler can handle this. But when I reduce the exception as shown above, it causes my application to crash and the DispatcherUnhandledException is not raised.

How to redraw an exception in a user interface thread to call a DispatcherUnhandledException?

When I used BackgroundWorker, the repeated exception did just that. Basically, I want to replace BackgroundWorker with Task, since Task has some really nice features that I would like to use.

+6
source share
2 answers

One way to solve this problem is to reset the exception in the Lambda expression contained in the statement. Sort of:

 Exception ex = t.Exception; Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => { throw ex; })); 

I do not recommend this, although it is a bit foul, but it answers the question!

Alternatively, you can do something similar, for example, against SynchronizationContext.Post .

+5
source

I have the same problem, although in my case the application does not crash, but the Application.DispatcherUnhandledException event never occurs. I also tried to use AppDomain.CurrentDomain.UnhandledException, which also does not work. I like to have a top-level exception handler to handle global errors that can occur in many places.

I have a library that I developed that uses an Event-Based Asynchronous Template (EAP), which I am modifying to use a Task-Based Asynchronous Template (TAP) instead to prepare for .NET 4.5, which has much better async support which based on tasks. With EAP, the Completed event is executed in the user interface thread, which is nice. Using Tasks, you should use TaskScheduler.FromCurrentSynchronizationContext (), as you mentioned above. I checked that ContinueWith code works in the user interface thread, and I threw an exception. So, I do not understand what is happening.

Hopefully this will be fixed in .NET 4.5 and hopefully for me prematurely switch from EAP to TAP. I love the fact that with TAP you can write things better. Calling Dispatcher.Invoke () looks a lot like bad.

+1
source

Source: https://habr.com/ru/post/894286/


All Articles