简体   繁体   中英

How to catch an Exception that has been thrown in the ContinueWith part of a task?

On a button_click event, I start a Task to do some time consuming calculations asynchronously. I use Task.ContinueWith and set the TaskSheduler for the continuation to the UI synchronization context to display the result of the asynchronous calculations in a Textbox .

Now lets say this last part throws an Exception like this:

private void button1_Click(object sender, EventArgs e)
{
   Task.Factory.StartNew(DoSomeCalculations).ContinueWith
      (t => { throw new Exception("Some Exception"); }, TaskScheduler.FromCurrentSynchronizationContext()); 
}

If I enable the debug option "Enable Just My Code" then the program halts and I get a warning: "Exception was unhandled by user code"

But if I don't set this option, the Exception disappears in nowhere (no program crash, just nothing).

So how/where can I handle this Exception?

Edit: Please note, as the tag suggests, I'm using .NET-4.0

If you want to handle the exception then either have a try/catch block inside the continuation itself, so that it handles its own exceptions or add an additional continuation to the continuation to handle exceptions.

Note that if you use await rather than ContinueWith to add continuations it's typically simpler, particularly when dealing with exceptions, as it will add the continuations on your behalf.

If you are using .NET framework 4.5, there's a new way to deal with Task objects.

private async void button1_Click(object sender, EventArgs e)
{
   await Task.Run(() =>
   {
       DoSomethingAsync()
   });
   //this line will run in UI thread
   throw new Exception("Some Exception");
}

And take note that any exception that's happening inside the Task object is swallowed inside the state machine created by the compiler when you use the async keyword. But this exception is set inside the Task object so basically you can still have reference to the exception using the Task object.

Something for your reference: http://blog.stephencleary.com/2012/02/async-and-await.html

According to best practices if we can't escape the use of async void methods (especially for event handlers), the try catch should be implemented in that method. But you need to make sure that all the async methods you are calling have the async Task method signature in order to catch the exception being thrown.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM