在没有等待的情况下返回异步方法的结果 - 坏主意?

时间:2015-04-03 17:01:13

标签: c# asynchronous async-await

我正在查看一段时间写的一些代码让我非常紧张。问题中方法的一般形状是这样的;

public Task Foo(...){

   SyncMethod();
   SyncMethod();
   ...
   return AsyncMethod();

}

我意识到我可以标记方法async并在最后一次调用时执行await,但是......我吗?这样可以安全使用吗?在最后一个async方法之前调用的同步方法没有异步替代方法,并且Foo方法不关心AsyncMethod的结果,因此看起来像一样好的,只需将等待返回给调用者并让调用者处理它。

此外,FWIW,有问题的代码可能是从一个运行有活动ASP.NET上下文的线程中调用的,所以我在脑中得到了那种刺痛的感觉。我在这里看不到的一些看不见的邪恶?

1 个答案:

答案 0 :(得分:5)

  

我意识到我可以标记方法async并在最后一次调用时执行await,但是......我吗?

实际上,如果你这样做了,它唯一的变化就是这些同步方法抛出的异常将被包装到返回的Task中,而在当前实现中,该方法将永远不会抛出成功返回Task。同步完成工作的实际效果以及异步完成的工作完全不受影响

话虽如此,两个你提到的选项令人担忧。在这里你有一个似乎是异步的方法,这意味着有人调用它期望它或多或少立即返回,但实际上该方法将同步运行一段时间。

如果你的两个同步方法非常快,那么你就相信这个非常少量的同步工作对你的任何一个调用者来说都不会引人注意,那就没关系了。但是,如果这项工作(甚至可能)需要花费很多时间来解决,那么你手上就有问题了。

实际上这些方法的异步替代方案是最好的,但作为最后的手段,在你有更好的选择之前,你可以做的最好的事情就是await Task.Run(() => SyncMethod());这些方法(当然这意味着该方法现在需要标记为async)。