【问题标题】:Will HttpClient Async methods run in new threadsHttpClient Async 方法会在新线程中运行吗
【发布时间】:2017-04-05 16:53:41
【问题描述】:

我想知道.Net HttpClient async 方法是在新线程还是在主线程中运行。

例如,在我的控制台应用程序中,我调用 async 方法以使用 HttpClient.GetStringAsync 方法下载 URL 内容。

这个方法(GetStringAsync)会在新的单独线程中运行吗?

【问题讨论】:

  • 我建议你阅读这个问题:stackoverflow.com/q/37419572/5311735 并回答到最后。简而言之 - 如果不检查源代码(或者除非文档中提到),您无法准确判断。

标签: c# multithreading httpclient


【解决方案1】:

一般来说,异步 I/O 方法不使用单独的线程。我在我的博文There Is No Thread中详细解释了这一点。

但是,在这种特定情况下,这并不完全正确。 .NET 中基于WebRequest 的 API 长期以来一直支持异步操作,但实际上始终将 HTTP 代理检测和 DNS 查找作为同步进行,即使通过它们的异步 API 也是如此。当HttpClient 开始流行时,这一点就被注意到了。不幸的是,微软决定修复这些长期存在的错误。

因此,HttpClient 将其WebRequest 调用包装在线程池线程中。请注意,它仍然使用“异步”API,因此只有同步部分(HTTP 代理和 DNS 查找)在线程池线程上完成;请求的其余部分是真正异步的。至少,对于一些平台来说是这样。

【讨论】:

  • 我在看这个例子 msdn.microsoft.com/en-ca/library/mt674882.aspx 。幸运的是,有 HttpClient 示例。在该链接中,有一个名为 Thread 的部分,他们提到不会在 async-await 上下文中创建额外的线程。您认为该部分与示例无关吗?
  • The async and await keywords don't cause additional threads to be created. - 这句话完全正确。 asyncawait 都不会创建新线程。
  • @StephenCleary - 我很惊讶地听到 .NET 自己的 GetStringAsync 实际上并不是真正的异步......至少可以安全地假设大多数其他带有 Async 的 .NET 方法在名称中真的是异步的并且不创建线程吗?比如 File.WriteAsync。
  • @mmcrae: 不。特别是对于File,除非将异步标志传递给构造函数,否则 I/O 不是异步的。
  • @StephenCleary 听起来异步 IO 没有我想象的那么启用。我想我很惊讶,因为我从您和其他人的帖子中了解到,至少在 Windows 上的大多数 IO 都是真正的异步(无线程)。讨论说要在 .NET 中对所有 ...Async 方法使用异步。我认为async / await 的一个重点是通过框架和硬件访问已经存在的真正异步行为。
【解决方案2】:

没有。因为使用 async/await 主要是为了异步完成 IO-bound 任务而不是创建新线程而创建的。只有 CPU 密集型任务才会创建新线程。

【讨论】:

  • 此声明证明的任何链接?
  • C# 编程考试参考书 70-483
  • @DigheadsFerke 页面?
  • 第 17 页:异步代码解决了这个问题。您不会在 I/O 操作完成之前阻塞您的线程,而是返回一个表示异步操作结果的 Task 对象。通过在此任务上设置延续,您可以在 I/O 完成后继续。同时,您的线程可用于其他工作。当 I/O 操作完成时,Windows 会通知运行时,并将继续任务安排在线程池上。
  • 第 19 页:因此,执行 CPU 密集型任务与 I/O 密集型任务不同。 CPU 密集型任务总是使用一些线程来执行它们的工作。异步 I/O 绑定任务在 I/O 完成之前不会使用线程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-04
  • 1970-01-01
  • 2015-01-31
  • 2018-11-29
  • 2014-01-09
  • 1970-01-01
相关资源
最近更新 更多