【问题标题】:Why compiler does not allow using await inside catch block为什么编译器不允许在 catch 块中使用 await
【发布时间】:2012-10-04 12:00:30
【问题描述】:

假设我有一个异步方法:

public async Task Do()
{
    await Task.Delay(1000);
}

另一种方法是尝试在catch 块内调用Do 方法

public async Task DoMore()
{
    try
    {
    }
    catch (Exception)
    {
        await Do(); //compiled error.
    }
}

但是这种方式,编译器不允许在catch中使用await,在幕后有什么原因我们不能那样使用它吗?

【问题讨论】:

标签: c# asynchronous async-await c#-5.0


【解决方案1】:

更新

这将在 C# 6 中得到支持。事实证明,这从根本上来说并非不可能,并且团队想出了如何做到这一点而不会在实现中发疯 :)

原答案

我强烈怀疑是同一个人reasoning that prevents yield return from being used in a catch block

特别是:

首先,我们仍然有一个问题,即“转到”到受 try-protected 区域的处理程序中间是非法的。进入 catch 块的唯一方法是通过捕获异常的“非本地 goto”。所以一旦你退出了 catch 块,下次调用 MoveNext 时,我们就无法回到我们离开的 catch 块了。

其次,抛出和捕获的异常是 catch 块执行的内在部分,因为它可以使用“空抛出”语法重新抛出。我们无法在对 MoveNext 的调用中保留该状态。

将“yield”替换为“await”,我想你会得到答案的。

感觉在大多数情况下想要做是一件奇怪的事情,你应该通常能够相当容易地重写你的代码以等待catch 块 - 当然,除非您试图等待某些东西然后抛出。那样的话会有点痛苦,我承认……

【讨论】:

  • 但在我的情况下,我有一个 HttpResponseMessage 对象,在 Web 调用失败后将从该对象中提取来自服务器的响应。如果我在 catch 语句之后执行此操作,则响应对象将被释放。
  • @Suny:不清楚你的意思,但听起来你应该问一个新问题。
  • @JonSkeet --“当然,除非你试图等待某些东西然后扔掉。在那种情况下,我承认这会有点痛苦” > Etienne Maheu 在 svick 的回答下的评论this question 很合适。
  • @roryap:更好的是,只要使用 C# 6 就可以了 :) 我已经编辑了我的答案。
猜你喜欢
  • 2011-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-27
  • 2014-09-13
相关资源
最近更新 更多