使用 void 进行异步异常处理 [英] Async exception handling with void

查看:34
本文介绍了使用 void 进行异步异常处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Async CTP 编写一个 IO 繁重的控制台应用程序.但我遇到了异常问题.

I'm using Async CTP to write an IO heavy console app. But I'm having problems with exceptions.

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();
}

然后发生以下情况:完成"被写入控制台,然后我在调试器中得到异常,然后按继续我的程序存在.
什么给?

And the following happens: "done" gets written to the console, then I get the exception in the debugger, then I press continue my program exists.
What gives?

推荐答案

当您调用 DoSomething() 时,它基本上会在幕后创建一个 Task 并启动该 任务.因为你有一个 void 签名,所以没有 Task 对象来发信号或者你可以阻止,所以执行直接结束.同时任务抛出一个异常,没有人捕捉到,我怀疑这就是你的程序终止的原因.

When you call DoSomething() it basically creates a Task under the hood and starts that Task. Since you had a void signature, there is no Task object to signal back or that you could have blocked on, so execution fell straight through to done. Meanwhile the task throws an exception, which nobody is catching, which, I suspect, is why your program terminates.

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

I think the behavior you wanted is more like this:

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 抛出时退出循环.当然,那么你并没有真正做任何异步的事情.但是从伪代码中,我不能完全确定您想要异步发生什么.

This will block on each DoSomething until it's done and exit the loop if DoSomething threw. Of course, then you are not really doing anything async. But from the pseudo code, i can't quite tell what you wanted to happen asynchronously.

主要内容:将 void 用于异步方法意味着您失去获取异常的能力,除非您正在await该异步方法.作为同步调用,它基本上只是安排工作,结果消失在以太中.

Main take-away: Using void for an async method means that you loose the ability to get the exception unless you are awaiting that async method. As a sync call it basically just schedules work and the outcome disappears into the ether.

这篇关于使用 void 进行异步异常处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆