使用语句并等待关键字在C#中发挥很好


101

我遇到一种情况,我正在async调用返回和IDisposable实例的方法。例如:

HttpResponseMessage response = await httpClient.GetAsync(new Uri("http://www.google.com"));

现在async,在现场之前,使用IDisposable实例时,使用“ response”变量的此调用和代码将包装在using语句中。

我的问题是,当async关键字混入时,这是否仍然是正确的方法?即使代码可以编译,在下面的两个示例中,using语句仍可以按预期工作吗?

例子1

using(HttpResponseMessage response = await httpClient.GetAsync(new Uri("http://www.google.com")))
{
    // Do something with the response

    return true;
}

例子2

using(HttpResponseMessage response = await httpClient.GetAsync(new Uri("http://www.google.com")))
{
    await this.responseLogger.LogResponseAsync(response);

    return true;
}

Answers:


97

是的,应该没问题。

在第一种情况下,您实际上是在说:

  • 异步等待,直到我们得到响应
  • 使用并立即处理

在第二种情况下,您是在说:

  • 异步等待,直到我们得到响应
  • 异步等待,直到我们记录了响应
  • 处理回应

using异步方法中的一条语句是“奇数”的,因为Dispose调用可能在与获取资源的线程不同的线程中执行(取决于同步上下文等),但仍会发生...假设您正在等待不断显示出来或失败,当然。(就像Dispose您的using语句包含对永不返回的方法的调用一样,您最终不会以非异步代码进行调用。)


4
谢谢乔恩。尽管大多数异步内容对我来说仍然是巫毒

@JonSkeet是否应该等待甚至在一个using(){...}块内使用,否则可能会导致性能下降?using(){...}的目的是否相同await
nam

1
@nam:不,using并且await有完全不同的目的。请注意,C#8现在也具有异步处理功能。尽管我的答案强调了线程问题,但是这绝对不意味着混用和错误是值得的。usingawait
乔恩·斯基特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.