【问题标题】:Don't wait for async method but VS gives warning不要等待异步方法,但 VS 会发出警告
【发布时间】:2019-11-12 08:52:59
【问题描述】:

我正在开发 WebAPI,其中一个 WebApi 操作方法调用了另一个方法,其中包含我不想等待的 Async 方法。打电话就忘了。

public async Task<IHttpActionResult> Convert(....)
{
//......
//VS warning here
 _asyncJobService.SendWebHook();
//......
}

    public async Task<HttpResponseMessage> SendWebHook()
    {
      //Send and forget, don't wait for result
      return await httpClient.GetAsync("http://stackoverflow.com");
    }

我从 VS 得到的警告是

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

在没有 VS 警告的情况下连接所有内容的正确方法是什么?

【问题讨论】:

  • 您可以在代码中明确禁用警告。 VS 应该提供“快速修复”来插入它。
  • 如果您在通话结束后不打算做某事,则不需要 await in SendWebHook。您可以将方法简化为public Task&lt;HttpResponseMessage&gt; SendWebHook()=&gt;httpClient.GetAsync("http://stackoverflow.com");
  • 对于警告,将任务分配给变量或_,无需等待。 asyncawait 不会让任何东西异步运行,它们有助于 await 已经运行的操作。如果您使用_ =SendWebHook();,则该任务将被丢弃并且不会生成警告
  • 请注意:关于命名异步方法的guideline 是将“异步”后缀附加到方法的名称中。

标签: c# asynchronous async-await


【解决方案1】:

首先,你不需要SendWebHook() 中的asyncawait,除非你打算在等待GetAsync 之后做某事。但是,在这种情况下,您只需返回即可。

asyncawait 不会让任何东西异步运行,它们有助于等待已经运行的操作。

asyncis just a keyword that tells the compiler the method is going to useawait. In response, the compiler generates a state machine similar to the one used for iterator methods.await` 反过来,等待已经执行异步操作,它不会使任何东西本身异步运行。

在这种情况下,HttpClient.GetAsync 是一个异步网络操作,无论其结果是否等待都会运行。

您可以将该方法简化为:

public Task<HttpResponseMessage> SendWebHook()=>httpClient.GetAsync("http://stackoverflow.com");

至于警告,您可以将返回的任务分配给变量或使用_ 丢弃它:

_ =SendWebHook();

这告诉编译器你真的不想对那个任务做任何事情

但是

您确定要这样做,尤其是使用 GET 请求吗?你不在乎那个请求返回什么吗?即使是健康检查 ping,您也可能确实关心监控服务器是否已关闭或超时

【讨论】:

  • 当没有等待警告并且代码将在分离的线程上运行并且不会阻塞执行时,也许我应该将 SendWebHook 方法包装到 Task.Run()?
  • @Tomas 为什么? GetAsync 是一个异步方法,即使您在 Task.Run 中调用它,它也不会在其他线程上执行任何操作。你只会浪费另一个线程等待已经异步的操作
  • 我是否正确理解如果执行 Async 方法并且我们不等待它,那么不会阻塞任何主线程并且不会等待 async 方法完成?至于第二个关于实现的问题,这是一个WebHook的方法,用户输入url获取通知并执行该方法。由于实现性质,我们不记录 WebHooks 结果,因此我们也不关心 Method 结果。
  • 没有。我已经解释过asyncawait 只是 语法糖,可以轻松等待已经异步的操作。 GetAsync已经异步运行。在任何情况下,Webhooks 都使用 POST,而不是 GET,而且您可能确实关心死掉的 webhooks。您不想在连续第 100 次失败后继续呼叫死客户 - 正在为出站流量付费。
猜你喜欢
  • 1970-01-01
  • 2021-11-26
  • 2012-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-10
  • 2018-02-23
  • 2016-11-03
相关资源
最近更新 更多