如何使用相同的httpHandler更改每个请求的代理和cookie容器?

时间:2018-03-07 09:51:38

标签: c# http httpclient

我有千个代理和千个自定义cookie。

现在我想用随机代理发送请求,并根据请求使用随机cookie。我曾尝试每次创建新的httpClientHandlerhttpClient,但最终会使用我对系统的所有记忆。

阅读this article后,我了解到我应该重复使用相同的httpClient。但在第一次请求后,httpClienthttpClientHandler的属性也无法修改。

  

此实例已启动一个或多个请求。只能在发送第一个请求之前修改属性。

所以我在发送请求之前已经习惯更改webProxy.Address以更改代理。它运行良好但在多线程情况下失败。它最终使用错误的代理请求。有没有其他方法来实现我的目标?感谢。

附加参考: HttpClientHandler / HttpClient Memory Leak

在上述参考文献中引用其他用户:

  

感谢您深究这一点。不幸的是,HttpClient类不符合我的要求 - 由于公共代理的动态和不稳定性,通常需要重新创建对象。看来HttpClient对于短生命连接来说不是一个可行的解决方案 - 更改代理设置需要重新构建HttpClientHandler,从而重新构建HttpClient。无论哪种方式,物体应该能够在不泄漏的情况下根据需要长寿或短缺;这肯定是HttpClient中的一个缺陷。

1 个答案:

答案 0 :(得分:5)

对于其他评论的进一步调查和参考,我相信这可以解决我的问题。

我们不应该重复使用相同的处理程序和客户端,而应该在每次线程安全请求时重新创建它。

总之,解决短期请求的内存泄漏问题。 我们可以关闭keep-alive,以便在响应之后关闭连接。

var client = new HttpClient();
client.DefaultRequestHeaders.ConnectionClose = true;
  

但事实证明,这可以为每个HTTP调用增加大约35ms(带有长尾,即放大异常值),使您无法利用重新使用套接字的好处。

因此我们可以将keep-alive更改为更短,而不是关闭keep-alive。

var sp = ServicePointManager.FindServicePoint(new Uri("http://foo.bar/baz/123?a=ab"));
sp.ConnectionLeaseTimeout = 60*1000; // 1 minute

参考: Singleton HttpClient? Beware of this serious behaviour and how to fix it