Why can't I catch an exception from async code?

ぃ、小莉子 提交于 2019-11-27 01:42:24

You have the "Just my code" Option turned on. With this on, it is considering the exception unhandled with respect to "just your code"--because other code is catching the exception and stuffing it inside of a Task, later to be rethrown at the await call and caught by your catch statement.

Without being attached in the debugger, your catch statement will be triggered, and it will run as you expect. Or you can just continue from within the debugger and it will run as expected.

The better thing to do is to just turn off "Just my code". IMO, it causes more confusion than it is worth.

As SLaks said, your code works fine.

I strongly suspect you over-simplified your example, and have an async void in your code.

The following works fine:

private static void Main(string[] args)
{
    CallAsync();
    Console.Read();
}

public static async void CallAsync()
{
    try
    {
        await DoSomething();
    }
    catch (Exception)
    {
        // Handle exceptions ?
        Console.WriteLine("In the catch");
    }
}

public static Task DoSomething()
{
    return Task.Run(() =>
    {
        throw new Exception();
    });
}

The following doesn't work:

private static void Main(string[] args)
{
    CallAsync();
    Console.Read();
}

public static void CallAsync()
{
    try
    {
        DoSomething();
    }
    catch (Exception)
    {
        // Handle exceptions ?
        Console.WriteLine("In the catch");
    }
}

public static async void DoSomething()
{
    await Task.Run(() =>
    {
        throw new Exception();
    });
}

See http://msdn.microsoft.com/en-us/magazine/jj991977.aspx

Async void methods have different error-handling semantics. When an exception is thrown out of an async Task or async Task method, that exception is captured and placed on the Task object. With async void methods, there is no Task object, so any exceptions thrown out of an async void method will be raised directly on the SynchronizationContext that was active when the async void method started. Figure 2 illustrates that exceptions thrown from async void methods can’t be caught naturally.

Your code won't even compile cleanly at the moment, as the x++; statement is unreachable. Always pay attention to warnings.

However, after fixing that, it works fine:

using System;
using System.Threading.Tasks;

class Test
{
    static void Main(string[] args)
    {
        DoSomething(10).Wait();
    }

    public static async Task DoSomething(int x)
    {
        try
        {
            // Asynchronous implementation.
            await Task.Run(() => {
                throw new Exception("Bang!");
            });
        }
        catch (Exception ex)
        {
            Console.WriteLine("I caught an exception! {0}", ex.Message);
        }
    }
}

Output:

I caught an exception! Bang!

(Note that if you try the above code in a WinForms app, you'll have a deadlock because you'd be waiting on a task which needed to get back to the UI thread. We're okay in a console app as the task will resume on a threadpool thread.)

I suspect the problem is actually just a matter of debugging - the debugger may consider it unhandled, even though it is handled.

Instead of using await, access the Task.Result property and put a try and catch around that access. You can also follow the example here and try that style.

Keep in mind that all exceptions thrown inside the context of a task thread are wrapped in an AggregateException.

The exception is not cuaght. The reason is - when below statement is executed

await Task.Run(() => {
            throw new Exception("Bang!");
        });

its on a separate thread. The exception raised on that thread goes uncaught.

change it to look like as below

await Task.Run(() => {

                try
                {
                    throw new Exception("Bang!");
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);   
                }

        });
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!