c# - HttpClient 提供的不是真正的异步操作吗?

标签 c# asp.net multithreading asynchronous async-await

我对异步 IO 操作感到困惑。在 this article Stephen Cleary 解释说我们不应该使用 Task.Run(() => SomeIoMethod()) 因为真正的异步操作应该使用

standard P/Invoke asynchronous I/O system in .NET

http://blog.stephencleary.com/2013/11/there-is-no-thread.html

However, avoid “fake asynchrony” in libraries. Fake asynchrony is when a component has an async-ready API, but it’s implemented by just wrapping the synchronous API within a thread pool thread. That is counterproductive to scalability on ASP.NET. One prominent example of fake asynchrony is Newtonsoft JSON.NET, an otherwise excellent library. It’s best to not call the (fake) asynchronous versions for serializing JSON; just call the synchronous versions instead. A trickier example of fake asynchrony is the BCL file streams. When a file stream is opened, it must be explicitly opened for asynchronous access; otherwise, it will use fake asynchrony, synchronously blocking a thread pool thread on the file reads and writes.

他建议使用 HttpClient 但内部使用 Task.Factory.StartNew() enter image description here

这是否意味着 HttpClient 不提供真正的异步操作?

最佳答案

Does this mean that HttpClient provides not truly async operations?

有点。 HttpClient 处于一个不寻常的位置,因为它的主要实现使用 HttpWebRequest,它只是部分异步。

特别是 DNS 查找是同步的,我认为代理解析也可能是同步的。之后,一切都是异步的。因此,对于 大多数 场景,DNS 速度很快(通常缓存)并且没有代理,因此它以异步方式运行。不幸的是,有足够多的场景(尤其是在公司网络内部)同步操作会导致严重滞后。

因此,当团队编写HttpClient 时,他们有三个选择:

  1. 修复 HttpWebRequest(和 friend )允许完全异步操作。不幸的是,这会破坏相当多的代码。由于在这些对象中使​​用继承作为扩展点的方式,添加异步方法将是向后不兼容的。
  2. 编写自己的 HttpWebRequest 等价物。不幸的是,这需要很多的工作,而且他们会失去与现有 WebRequest 相关代码的所有互操作性。
  3. 将对线程池的请求排队以避免最坏的情况(阻塞 UI 线程上的同步代码)。不幸的是,这会降低 ASP.NET 的可扩展性,依赖于空闲线程池线程,并且即使在最好的情况下也会产生最坏情况下的成本。

理想世界中(即,当我们有无限的开发人员和测试人员时间时),我更喜欢 (2),但我理解他们为什么选择 (3)。

附带说明一下,您发布的代码显示了一个 dangerous use of StartNew ,实际上 caused problems由于它使用了 TaskScheduler.Current。这has been fixed在 .NET Core 中 - 不确定修复程序何时会回滚到 .NET Framework 中。

关于c# - HttpClient 提供的不是真正的异步操作吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39931213/

相关文章:

java - 固定 ImageButton 在 GestureImageView 上的位置

c# - 如何将通用 IList<T> 转换为 IList?

C# ASP.NET MVC 5 -> ActionFilterAttribute -> 停止自动重定向 HTTP 401

javascript - 将 http 请求发送到第三方服务器并通过重定向获取响应

javascript - 如何从视频网址创建缩略图

C++ - 线程和多队列

multithreading - Golang线程不是每次都执行

c# - 列表模型 Razor View

c# - 访问路径 'C:\Users\amministratore\Documents\pippo.xml' 被拒绝

c# - C# DataGrid实时更新