async 和 await 可以省略吗?

Async and await may be elided?

我有这个简单的代码:

 public async  Task<string> GetAsync()
   {
      var httpClient = new HttpClient();
      return await httpClient.GetStringAsync("...");
   }

但是 Resharper 说:

当我使用变量时,这个警告消失了:

 public async  Task<string> GetAsync()
        {
            var httpClient = new HttpClient();
            var st = await  httpClient.GetStringAsync("...");
            return st;
        }

我已经知道这样做的危险

 using (var httpClient = new HttpClient())
 return  httpClient.GetStringAsync("...");

(任务将被取消)

但这不是我的情况,因为我使用的是 await(而不是 using)。

问题:

为什么 Resharper 会警告我?

你的方法"can"重写如下:

public Task<string> GetAsync()
{
    var httpClient = new HttpClient();
    return httpClient.GetStringAsync("...");
}

从而避免了编译 async 方法然后使用 await 进行昂贵的控制流切换的开销。功能还是一样的。这就是 R# 告诉您的内容 - 您可以省略 async/await 并避免不必要的开销。

但是,我把 "can" 放在引号中,因为你的代码很臭,因为首先,HttpClient 是一个 IDisposable,所以你应该在使用后处理它.那么 async/await 将是必要的:

public async Task<string> GetAsync()
{
    using(var httpClient = new HttpClient())
    {
        return await httpClient.GetStringAsync("...");
    }
}

因为这将被翻译成等价的

public async Task<string> GetAsync()
{
    var httpClient = new HttpClient();
    var result = await httpClient.GetStringAsync("...");
    httpClient.Dispose();
    return result;
}

这个你绝对应该修复。其次,需要考虑的一件事是创建 HttpClients 可能会悄悄地破坏你的应用程序,因为 HttpClients 应该被重用。参见 this blog post and this SE Stack Exchange post