实例化 HttpClient 时,一个常见的建议是:
-
使用单例,每次使用后不要丢弃 https://stackoverflow.com/questions/22560971/what-is-the-overhead-of-creating-a-new-httpclient-per-call-in-a-webapi-client.
然而,基于在这个链接上 https://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.110).aspx我看到评论,我认为这暗示着另一条规则:
HttpClient 类实例充当发送 HTTP 请求的会话。 HttpClient 实例是应用于该实例执行的所有请求的设置的集合。此外,每个 HttpClient 实例都使用自己的连接池,将其请求与其他 HttpClient 实例执行的请求隔离。
这让我想知道是否应该为与之交互的每个服务端点创建一个 HttpClient 实例。我所说的“服务端点”是指一个不同的基地址。以下每个都是不同的“服务端点”:
- "http://foo.net/api/Message/ http://foo.net/api/Message/"
- "http://bar.com/api/Message/ http://bar.com/api/Message/"
- "http://wow.gov/api/Message/ http://wow.gov/api/Message/"
- "http://now.com/api/Message/ http://now.com/api/Message/"
- "http://mom.org/api/Message/ http://mom.org/api/Message/"
- "http://dog.com/api/Message/ http://dog.com/api/Message/"
当然,如果我打算使用 HttpClient 的“BaseAddress”属性,并且要处理并发调用,那么我需要为每个“服务端点”拥有一个 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,我是否做错了什么?
我是否真的需要上面引用中提到的“连接池隔离”?