如何使用异步等待处理多个异常

时间:2015-09-01 20:46:49

标签: .net multithreading visual-studio asynchronous async-await

我遵循Microsoft在此处指定的模式。 https://msdn.microsoft.com/en-us/library/hh191443.aspx

本文将介绍如何使用await开发异步代码。但是,他们没有谈论在await返回之前发生异常时会发生什么。

在下面的示例中,外部异常结束父线程,并且任务没有线程可以返回。我该如何处理这个scneario?

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

        public static async void CallAsync()
        {
            var task = CallExceptionAsync();
            ThrowException("Outside");
            await task;
        }

        public static Task CallExceptionAsync()
        {
            return Task.Run(() =>
            {
                ThrowException("Inside");
            });

        }

        public static void ThrowException(string msg)
        {
            throw new Exception(msg);
        }        
    }

2 个答案:

答案 0 :(得分:0)

您必须准备好通过使用try / catch包围该调用来处理可能已经渗透回主线程的异常。在这种情况下,您应该收到一个AggregateException,它包含您开始的异步线程中的一个或多个异常。

答案 1 :(得分:0)

这正是您不应该使用async void的原因。在常规异步方法中,捕获从方法主体抛出的异常并将其存储在返回的任务中。因为在async void的情况下,调用者没有任何观察异常的任务会导致进程停止。

因此,您应该返回一项任务,如果是Main,您可以与Task.Wait同步阻止:

private static void Main()
{
    CallAsync().Wait();
}

public static async Task CallAsync()
{
    var task = CallExceptionAsync();
    ThrowException("Outside");
    await task;
}

使用Task.Wait进行阻止不适合真正的应用,因为它可能导致涉及SynchronizationContext的死锁。在这种情况下,您可以使用Stephen Cleary的AsyncContext