在实例化HttpClient时,一个常见的建议是:
但是,基于on this link,我认为评论意味着另一条规则:
HttpClient类实例充当发送HTTP请求的会话。 HttpClient实例是应用于该实例执行的所有请求的设置集合。此外,每个HttpClient实例都使用自己的连接池,将其请求与其他HttpClient实例执行的请求隔离开来。
这让我想知道我是否应该为每个与之交互的服务端点创建一个HttpClient实例。通过“服务端点”,我的意思是一个不同的基地址。以下各项将是一个独特的“服务端点”:
当然,如果我打算使用HttpClient的“BaseAddress”属性,并且如果我正在处理并发调用,那么每个“service-endpoint”需要一个HttpClient实例。
但是,HttpClient允许我明确指定一个绝对地址:
HttpClient client = new HttpClient(...);
client.PostAsJsonAsync("http://foo.net/api/Message/", ...);
client.PostAsJsonAsync("http://bar.com/api/Message/", ...);
client.PostAsJsonAsync("http://wow.gov/api/Message/", ...);
client.PostAsJsonAsync("http://now.com/api/Message/", ...);
client.PostAsJsonAsync("http://mom.org/api/Message/", ...);
client.PostAsJsonAsync("http://dog.com/api/Message/", ...);
上面的代码可以工作,这正是我想要的当前应用程序的构建。但是唠叨的问题仍然存在......如果我将一个HttpClient用于我的应用程序与之通信的所有服务端点,那么我做错了什么?
为什么我真的需要上面引文中提到的“连接池隔离”?
答案 0 :(得分:2)
但是我想知道我是否会影响其内部运作 HttpClient因为我使许多端点共享相同的连接 池。
不,我不认为HttpClient
的单个实例会耗尽您的资源,但这实际上取决于您要做多少并发请求。 HttpClient
旨在为并发请求提供服务,并且通过使用异步API(XXXAsync
),您可以实现这一目标。
我建议不要忘记将ServicePointManager.DefaultConnectionLimit
设置为更高的数字,因为它的默认值是2(并发请求)。
此外,如果您认为自己会使用单个实例快速上线,我建议您一如既往地了解应用程序以了解确切的瓶颈。
答案 1 :(得分:1)
我也面临着同样的问题。
我的调查结果如下:
使用HttpClient
的单独实例,即使您需要在请求期间更改其非线程安全设置(DefaultRequestHeaders, BaseAddress
)。使用每个实例的那些特定设置来创建单独的实例将是有用且安全的。更多详细信息:HttpClient–Is It Really Thread-Safe?
好,我创建了HttpClient
的特定实例,但是我不想使用BaseAdress
。从第1点开始,我需要针对每个唯一的BaseAdress
(主机)使用新的HttpClient实例。
但是,如果我使用HttpClient
到多个没有绝对地址BaseAdress
的主机的请求该怎么办?
您可以追踪从HttpClient
到SocketsHttpHanlder
到HttpConnectionPoolManager
(dotnet source code)的调用,并看到它为每个主机创建了单独的'HttpConnectionPool'并将池添加到'ConcurrentDictionary'_pools 。也就是说,无论如何,我们为每个唯一主机都有一个单独的池。
这就是为什么我更愿意为多个主机使用单个HttpClient
实例而不使用BaseAdress
。