user788454
user788454

Reputation:

How to catch exception in an async method?

I am learning async and await. The following "catch" does not catch the exception thrown in DoTask. Assuming DoTask is a third party method that I can't change, how do I fix it so that the catch clause does catch the exception?

private static async Task DoTask()
{
    await Task.Delay(10000);
    throw new Exception("Exception!");
}


public static void Main(string[] args)
{
    try
    {
        Task.Run(async () => await DoTask());
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }

    Console.WriteLine("End");
    Console.ReadKey();
}

Upvotes: 3

Views: 1237

Answers (3)

Yom B
Yom B

Reputation: 238

Catching AggregateException will be possible only if the task is awaited. So when you do not await the Task.Run, the executing thread moves out of the try block and now you can't catch the exception in case it occurs. As for the AggregateException - it is a wrapper which holds one or more exceptions which you can access inside its property InnerExceptions. I suggest this fantastic read for in depth about this topic and threading in C# in general: http://www.albahari.com/threading/part5.aspx#_Working_with_AggregateException

Also you check this out: https://www.youtube.com/watch?v=J0mcYVxJEl0 (around 26:00 is the answer, but a great talk in general!)

Upvotes: 1

user788454
user788454

Reputation:

I worked out - I need to wait for the task to finish. After I added the "Task.WaitAll(task);", it caught the exception.

private static async Task DoTask()
{
    await Task.Delay(10000);
    throw new Exception("Exception!");
}


public static void Main(string[] args)
{
    try
    {
        Task task = DoTask();
        Task.WaitAll(task);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.InnerException.Message);
    }

    Console.WriteLine("End");
    Console.ReadKey();
}

Upvotes: 1

Enigmativity
Enigmativity

Reputation: 117027

How about this simplification:

public static async Task Main(string[] args)
{
    try
    {
        await DoTask();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }

    Console.WriteLine("End");
    Console.ReadKey();
}

Upvotes: 5

Related Questions