我遵循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);
}
}
答案 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
。