HttpClient可以安全地同时使用吗?

Ale*_*x K 147 .net concurrency c#-4.0 dotnet-httpclient

在我可以找到的所有示例中HttpClient,它用于一次性呼叫.但是,如果我有一个持久的客户端情况,可以同时进行多个请求怎么办?基本上,client.PostAsync对同一个实例一次调用2个线程是安全的HttpClient.

我不是在寻找实验结果.作为一个工作示例可能只是一个侥幸(并且持久的),一个失败的例子可能是一个错误的配置问题.理想情况下,我正在寻找HttpClient中并发处理问题的一些权威答案.

Mar*_* N. 145

根据MSDN,自.NET 4.5以下实例方法是线程安全的(感谢@ischell):

CancelPendingRequests
DeleteAsync
GetAsync
GetByteArrayAsync
GetStreamAsync
GetStringAsync
PostAsync
PutAsync
SendAsync
Run Code Online (Sandbox Code Playgroud)

  • 最近,但我想对@cwills发表评论.DefaultRequestHeaders只是默认值.如果您需要基于每个请求的不同标头,您可以创建新的StringContent(),在其上设置其他标头,然后使用带有URI和HttpContent的重载. (7认同)
  • 所以Microsoft设计的HttpClient是可重用的,但是该类具有头文件的实例数据:client.DefaultRequestHeaders.Accept.Add(...); (5认同)
  • @ischell:我可以向你保证,在讨论这个问题时,有问题的段落**并非**. (4认同)
  • 是的,我不确定那个,因为它似乎是对MSDN上所有内容的标准警告(我记得读过一些MSDN博客,关于某些时候警告是错误的,因为它是盲目地应用于所有事情). (3认同)
  • 这是错的; 在您链接的MSDN页面的备注部分中,它表示GetAsync,PostAsync等都是线程安全的. (3认同)
  • 另一方面,`HttpClient`有一个[CancelPendingRequests](http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.cancelpendingrequests(v = vs.110).aspx) "取消[s]此实例上的所有待处理请求." - 这似乎表明它可以在飞行中有多个请求. (2认同)
  • 我不确定 HttpClient 是否是线程安全的。这里有两种情况: 1. 调用 client.GetAsync(),等待它返回一个 Task 对象,然后再次调用它(在任何线程上) - 应该没问题 - 我们的调用没有并发。HttpClient 在后台处理请求并在请求完成后完成每个任务,或者 2. 在多个线程上重复调用 client.GetAsync() 而不等待每次返回 Task 对象。这是并发性,我怀疑这是开箱即用的支持。不保证异步方法提供线程安全(案例 #2)。 (2认同)
  • HttpClient 还有一个默认的每台服务器最大连接数 (`HttpClientHandler.MaxConnectionsPerServer`) 仅为 2。确保你增加它,否则你的多线程请求将被阻塞。 (2认同)
  • 此外,要在线程请求上设置不同的 Uri 和标头,您可以使用“HttpRequestMessage”并将其传递给“SendAsync”。 (2认同)

mur*_*uge 89

以下是Henrik F. Nielsen关于HttpClient的另一篇文章,他说:

" 默认的HttpClient是您可以开始发送请求的最简单方式.单个HttpClient可用于同时发送任意数量的HTTP请求,因此在许多情况下您只需创建一个HttpClient,然后将其用于所有请求. "

  • 如果用户名和密码可以在线程之间改变怎么办?这就是我似乎无法找到任何人谈论的东西 (9认同)
  • 请注意,对所有请求重复使用同一HttpClient可能会导致DNS问题过时:https://github.com/dotnet/corefx/issues/11224。 (2认同)

Ale*_*x K 15

由Henrik F. Nielsen(HttpClient的主要建筑师之一)发现了一篇MSDN论坛帖子.

快速摘要:

  • 如果您有相关的请求(或不会相互踩),那么使用相同的HttpClient会很有意义.
  • 在genral中,我建议尽可能多地重用HttpClient实例.