Where does an async Task throw Exception if it is not awaited?

后端 未结 3 2245
天涯浪人
天涯浪人 2021-02-19 13:06

I have the following example: (please also read comments in code, as it will make more sense )

public async Task> MyAsyncMethod() 
{
           


        
3条回答
  •  忘掉有多难
    2021-02-19 14:07

    As I don't await for the actual Result in the MyAsyncMethod and if PostAsync method throws an exception, in which context is the exception going to be thrown and handled?

    If you dont await any of the tasks in your code or dont assign a continuation, behavior may differ depending on the .NET framework version you're using. In both cases, the returned Task will swallow the exception, the difference will occur at finalization:

    1. .NET 4.0 - The finalizer thread will rethrow the swallowed exception. If no global exception handler is registered it will terminate th process

    2. .NET 4.5 and above - The exception will be swallowed and will go unnoticed.

    In both cases TaskScheduler.UnobservedTaskException event will trigger:

    Occurs when a faulted task's unobserved exception is about to trigger exception escalation policy, which, by default, would terminate the process.

    When an non async Task returning method executes synchronously the exception is propogated immediately and that is why you're catching the exception without using await, but you should definitely not be depending on that in your code.

    Is there any way I can handle exceptions in my assembly

    Yes, you can. I would advise you await on tasks you execute inside your assembly.

    There is no reason to be using the async modifier if you aren't awaiting anything:

    public Task PostAsync() 
    {
         return GetSomeTask();
    }
    

    Then, you can await on PostAsync and catch the exception there:

    public async Task MyAsyncMethod() 
    {
        try
        {
             // No need to use Task as await will unwrap the outter task
             return await _mySender.PostAsync();
         }
         catch (MyCustomException e)
         {
               // handle here
         }
    }
    

    You can even modify this code further and remove the async keyword and possibly catch the exception even higher up the callstack to the method calling MyAsyncMethod.

提交回复
热议问题