async 和await 可以被省略吗?

Roy*_*mir 2 c# resharper async-await

我有这个简单的代码:

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

然而雷沙珀说:

在此输入图像描述

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

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

我已经知道这样做的危险

 using (var httpClient = new HttpClient())
 return  httpClient.GetStringAsync("...");
Run Code Online (Sandbox Code Playgroud)

(任务将被取消)

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

问题:

为什么 Resharper 会警告我?

V0l*_*dek 5

您的方法“可以”重写如下:

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

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

但是,我将“can”放在引号中,因为您的代码很臭,因为首先,HttpClient是一个IDisposable,所以您应该在使用后处理它。那么就async/await需要:

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

因为这将被翻译成等价的

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

这个你绝对应该修复。其次,需要考虑的一件事是,创建HttpClients 可能会悄悄破坏您的应用程序的稳定性,因为HttpClients 应该被重用。请参阅此博客文章此 SE Stack Exchange 文章