我有类似以下的内容
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逻辑长时间运行之前发送回任何响应之前到达服务器的请求数。
有人可以解释为什么这个示例似乎超过2的ServicePointManager.DefaultConnectionLimit?我最好的猜测是,由于我为每个请求创建了一个新的HttpClient
,ServicePointManager
每个请求都会生成一个ServicePoint
个对象,但根据我的阅读,我认为ServicePointManager
应该只为每个唯一的架构和域创建ServicePoint
的不同实例,所以我不确定。
注意:我打算重新使用我的HttpClient
实例,但这个结果使我的好奇心达到了顶峰:)。
答案 0 :(得分:1)
为了防止其他人感到好奇,我稍微检查了HttpClient
代码,看起来每个HttpClient
实例化了HttpMessageHandler
个实例。除了HttpMessageHandler
定义的uri的模式和域之外,ServicePoint
对象为每个实例创建一个哈希码,用于创建HttpClient
个对象。
答案 1 :(得分:-1)
@ cjablonski76我相信你的解释是错误的。因为根据框架代码创建ServicePoint如下所示。
sp = new ServicePoint(address)
{
ConnectionLimit = DefaultConnectionLimit,
IdleSince = DateTime.Now,
Expect100Continue = Expect100Continue,
UseNagleAlgorithm = UseNagleAlgorithm
};
s_servicePointTable[tableKey] = new WeakReference<ServicePoint>(sp);
如果您看到这一点,则不会使用支持您的陈述的哈希码。