【问题标题】:Why do I get a compiler warning when using ContinueWith?为什么在使用 ContinueWith 时会收到编译器警告?
【发布时间】:2012-09-22 22:40:10
【问题描述】:

我有这行代码:

t.ContinueWith(_ => form.Close(), 
                  TaskScheduler.FromCurrentSynchronizationContext());

...关于编译器要说的:

警告 2 由于不等待此调用,因此在调用完成之前继续执行当前方法。考虑将 'await' 运算符应用于调用结果。

现在,这不是我编写的代码,但我认为它只是在现有任务的末尾添加一个延续。我不认为它实际上是 running 任务(或延续)。那么这个仅仅修改任务的过程肯定是同步操作吗?为什么我要await呢?

【问题讨论】:

  • 你能把整个方法贴出来吗?
  • 斯蒂芬,这是你的代码 :-) 见stackoverflow.com/a/12513296/98422
  • 没有周围的代码,我不确定,但为什么不只是等待t然后form.Close?
  • 周围的代码可以在上面的链接中找到(2 cmets up)。任务 t 已经在进行中,周围代码的重点是在 t 执行时显示一个进度对话框,因此 await-ing t 在这里不合适。
  • 这将教我在不编译的情况下发布代码! :)

标签: c# .net-4.5 compiler-warnings async-await


【解决方案1】:

我为什么要await它?

您不必await 它,这就是为什么它是一个警告,而不是一个错误。但是,如果您在 async 方法中,并且您有一个返回可等待对象的方法,则大多数情况下您不应该忽略它。

在正常的同步代码中,您无需执行任何特殊操作即可等到您调用的方法完成,每个方法调用总是阻塞。但是对于异步方法,如果你想等到它们完成,你实际上必须await它们。此外,如果异步操作失败并抛出异常,您将不会知道它,直到您 await 方法的结果(或以其他方式从结果中获取异常,例如调用 Wait() 如果等待是Task)。

因此,如果您在 async 方法中忽略返回的可等待值,则您的代码中可能存在错误,而这正是警告试图避免的。

在你的情况下,ContinueWith() 返回一个Task可以awaited,所以编译器假定你应该await它。但是在这种情况下,您不想等到继续完成并且Close() 很可能不会抛出异常。因此,在这种情况下,警告是误报,它实际上并不表示代码中存在问题。

【讨论】:

  • 很好的答案,谢谢。我能做些什么来阻止警告出现,从而掩盖所有实际问题吗? (我不想在其他情况下禁用警告,就在这里)。
  • 如果您在 then 方法之前添加 #pragma warning disable 4014 并在其后添加 #pragma warning restore 4014 ,则可以仅为此方法禁用它。通常,我会建议您修复警告所抱怨的内容,但在这种情况下,实际上没有什么需要修复的,因此我认为仅针对此方法禁用警告是有道理的。
  • 另一个选项是将任务分配给一个变量。然后简单地忽略该变量。
  • 谢谢@svick。如果那个警告编号是在该死的警告消息中,那不是很好吗,这样我就不需要浪费 10 分钟来追踪它了?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-16
相关资源
最近更新 更多