c#的每个HttpClient实例都有自己的ServicePoint
本文关键字:自己的 ServicePoint 实例 HttpClient | 更新日期: 2023-09-27 18:13:59
我有如下内容
public async Task PostTest()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("abc.com");
var response = await client.PostAsync("/api/call", new StringContent("hello world"));
//do something with response and dispose it.
//NOTE: server is long running, so dispose is not getting called before sending other remaning requests.
}
}
我依次从一个循环中调用这个方法来快速连续地发送大量的请求。
根据我对HttpClient
的了解,它将请求关联到特定的ServicePoint对象,该对象将具有默认的ConnectionLimit值2。因为我所有的请求都指向同一个uri,所以只应该创建一个ServicePoint
对象,因此限制了我最多两个并发请求(假设流水线关闭)。
我实际看到的运行这是,如果我调用我的PostTest()
方法在"同一时间"n次,我看到n请求的数量到达服务器之前任何响应被发送回来,因为服务器的api逻辑是长时间运行。
有人能解释一下为什么这个示例似乎超过了ServicePointManager。DefaultConnectionLimit = 2?我最好的猜测是,由于我每个请求创建一个新的HttpClient
, ServicePointManager
正在每个请求创建一个ServicePoint
对象,但从我所读到的,我认为ServicePointManager
应该只创建每个独特模式和域的ServicePoint
的不同实例,所以我不确定。
注意:我确实计划重用我的HttpClient
实例,但是这个结果满足了我的好奇心:)。
以防其他人好奇,我稍微检查了一下HttpClient
代码,看起来每个HttpClient
每个实例都实例化了一个HttpMessageHandler
。除了HttpClient
定义的uri的模式和域之外,HttpMessageHandler
对象还为每个实例创建一个用于创建ServicePoint
对象的哈希码。
我认为你的解释是错误的。因为根据框架代码,ServicePoint的创建如下所示:
sp = new ServicePoint(address)
{
ConnectionLimit = DefaultConnectionLimit,
IdleSince = DateTime.Now,
Expect100Continue = Expect100Continue,
UseNagleAlgorithm = UseNagleAlgorithm
};
s_servicePointTable[tableKey] = new WeakReference<ServicePoint>(sp);
如果你看到这个,说明没有使用hashcode来支持你的语句