3

I'm trying to deal with exceptions inside of tasks, so far I've looked at the following links:

https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/exception-handling-task-parallel-library

How to handle Task.Run Exception

If I am correct, they suggest that the following code would not cause a User-Unhandled Exception.

    public async void TestMethod()
    {
        try
        {
            await Task.Run(() => { throw new Exception("Test Exception"); });
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }

However, I am getting a User-Unhandled Exception. I want to handle the exception outside of the Task so I can avoid writing code for changing the UI from a different thread. What am I doing wrong?

Here is a printscreen of the exception:

enter image description here

David Andrew Thorpe
  • 838
  • 1
  • 9
  • 23
  • Why are you catching `AggregateException`? `AggregateException` is thrown by `Task.Wait()` and `Task.Result`, but you're awaiting your Task. You can just catch the exception directly -- `catch (Exception ex) { Console.WriteLine(ex.Message); }` – canton7 Aug 20 '19 at 16:33
  • @canton7 Hey, yes I was orignally just catching the one exception as you're saying. That was just me trying different things from one of the links I posted in the question – David Andrew Thorpe Aug 20 '19 at 16:34
  • The first link talks about `Task` in the context of the pre-async/await world: you can see that all of their examples use `Task.Wait()` / `Task.Result`. Your second link has answers which do `try { await ... } catch (Exception e) { ... }` – canton7 Aug 20 '19 at 16:36
  • So I think the answer here is simply "if you're using `await`, then you don't need to catch and unwrap `AggregateExceptions`". That's what you're doing wrong. – canton7 Aug 20 '19 at 16:36
  • @canton7 Yes, try { await ... } catch (Exception e) { ... } I believe is what I'm trying to achieve. I want to catch the exceptions from inside the task – David Andrew Thorpe Aug 20 '19 at 16:37
  • Cool! Problem solved then :) – canton7 Aug 20 '19 at 16:37
  • @canton7 Despite the Task being wrapped inside of a try/catch, I still am getting a user unhandled exception. – David Andrew Thorpe Aug 20 '19 at 16:38
  • Post your updated code, which doesn't catch AggregateException but instead just catches Exception – canton7 Aug 20 '19 at 16:40
  • @canton7 All done boss – David Andrew Thorpe Aug 20 '19 at 16:43
  • I have to commute, but that should be just fine. – canton7 Aug 20 '19 at 16:45
  • Unfortunately it's causing me problems :( Have a safe commute @canton7 – David Andrew Thorpe Aug 20 '19 at 16:47
  • 2
    What problems? I just tested the new code and it works exactly as expected (it writes "Test Exception" to the console) – Gabriel Luci Aug 20 '19 at 16:48
  • @GabrielLuci I'm super confused then. I'm calling that test method from my ViewModel constructor. What I will do to further isolate the problem is run it in a test project and provide printscreens, bare with me. – David Andrew Thorpe Aug 20 '19 at 16:50
  • @GabrielLuci I've added a print screen to the question – David Andrew Thorpe Aug 20 '19 at 16:56
  • 2
    That looks like Visual Studio is configured to break on all exceptions, even handled ones. Just hit F5 and it will probably continue execution into the `catch` block. – Gabriel Luci Aug 20 '19 at 16:57
  • @GabrielLuci You are absolutely right, I feel so silly hahaha. Post it as an answer? – David Andrew Thorpe Aug 20 '19 at 17:02

1 Answers1

3

To answer your original question, before you edited it, one of the features of await is that it will "unwrap" not only the return value, but any exceptions too. So if you need to catch an exception, it will not be an AggregateException like it would be if you used .Wait() or .Result.

That's a Good Thing™

Also, it looks like Visual Studio is configured to break on all exceptions, even handled ones. This is handy (I always keep VS set like that because sometimes weird things can happen when exceptions are caught and hidden), but you just have to be aware of it. You can press F5 or F10 to continue execution and it should continue into the catch block.

Gabriel Luci
  • 38,328
  • 4
  • 55
  • 84
  • 1
    Thanks so much! I thought I was going crazy! I've changed my exception settings now and it's working fine – David Andrew Thorpe Aug 20 '19 at 17:12
  • 1
    (to be very pedantic, it's `Task.Wait()` and `Task.Result` which *wrap* the Task's exception(s) in an AggregateException, and `await` rethrows it directly (in a way which preserves the stack trace)) – canton7 Aug 20 '19 at 17:56