使用void进行异步exception处理

我正在使用Async CTP编写IO重型控制台应用程序。 但我遇到exception问题。

public static void Main() { while (true) { try{ myobj.DoSomething(null); } catch(Exception){} Console.Write("done"); //... } } //... public async void DoSomething(string p) { if (p==null) throw new InvalidOperationException(); else await SomeAsyncMethod(); } 

并发生以下情况:“完成”被写入控制台,然后我在调试器中得到exception,然后我按继续我的程序存在
是什么赋予了?

当你调用DoSomething()它基本上会在DoSomething()创建一个Task并启动该Task 。 由于您有一个void签名,因此没有任何Task对象可以发出信号或者您可以阻止它,因此执行直接完成。 同时,该任务抛出一个exception,没有人抓住,我怀疑,这是你的程序终止的原因。

我认为你想要的行为更像是这样的:

 public static void Main() { while (true) { var t = myobj.DoSomething(null); t.Wait(); if(t.HasException) { break; } } Console.Write("done"); //... } } //... public async Task DoSomething(string p) { if (p==null) throw new InvalidOperationException(); else await SomeAsyncMethod(); } 

这将阻止每个DoSomething直到它完成并退出循环,如果DoSomething投掷。 当然,那时你并没有真正做任何异步。 但是从伪代码中,我不能完全告诉你想要异步发生什么。

主要内容:对异步方法使用void意味着除非await异步方法,否则将失去获取exception的能力。 作为同步调用,它基本上只是安排工作,结果消失在以太网中。

如果您为您的控制台应用程序提供异步兼容的上下文(例如,来自我的AsyncEx库的AsyncContext ( docs , source )),那么您可以捕获从该上下文传播的exception,即使是async void方法:

 public static void Main() { try { AsyncContext.Run(() => myobj.DoSomething(null)); } catch (Exception ex) { Console.Error.WriteLine(ex.Message); } Console.Write("done"); } public async void DoSomething(string p) { if (p==null) throw new InvalidOperationException(); else await SomeAsyncMethod(); }