在没有硬CPU使用情况下动态更改HttpClient中的代理

问题描述 投票:1回答:1

我需要创建一个多线程应用程序来发出请求(发布,获取等)为此我选择了Httpclient

默认情况下,它不支持Socks代理。所以我发现可以使用Sockshandlerhttps://github.com/extremecodetv/SocksSharp)代替基本的HttpClientHandler。它允许我使用袜子。

但我有一个问题。我的所有请求都应该通过我从互联网上解析的不同代理发送。但httpclient处理程序不支持动态更改代理。如果我没有有效的代理,我需要重新创建一个httclient,这没关系,但如果我有200个线程,则需要大量的cpu。那么在这种情况下我该怎么办?

第二个问题。我发现这篇文章(https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/)谈到使用HttpClient作为单个实例来提高性能,但在多线程程序中它是不可能的。在这种情况下哪种方式更好?

谢谢你的帮助

c# multithreading httpclient socks proxies
1个回答
1
投票

httpclient处理程序不支持动态更改代理。

我不确定这在技术上是否正确。 Proxy是一个读/写属性,所以我相信你可以改变它(除非这会导致运行时错误......我实际上没有尝试过它)。

更新:我现在尝试过,你的断言在技术上是正确的。在下面的示例中,更新UseProxy的行将失败,并显示“System.InvalidOperationException:'此实例已经启动了一个或多个请求。只能在发送第一个请求之前修改属性。'”在.NET Core和完整框架上确认。

var hch = new HttpClientHandler { UseProxy = false };
var hc = new HttpClient(hch);
var resp = await hc.GetAsync(someUri);

hch.UseProxy = true; // fail!
hch.Proxy = new WebProxy(someProxy);
resp = await hc.GetAsync(someUri);

但事实是,你不能以线程安全的方式为每个请求设置不同的属性,这是不幸的。

如果我有200个线程,则需要大量的cpu

并发异步HTTP调用不应消耗额外的线程或CPU。使用await Task.WhenAll或类似物品消灭它们并消耗there is no thread,直到返回响应。

第二个问题。我发现这篇文章......

这绝对是你需要注意的事情。但是,即使您可以为每个请求设置不同的代理,底层网络堆栈仍然需要为每个代理打开一个套接字,因此就套接字耗尽问题而言,您不会在每个代理的HttpClient实例上获得任何东西。

最好的解决方案取决于您在这里谈论的代理数量。在文章中,作者描述了当服务器命中大约4000-5000个开放套接字时遇到问题,并且在400或更少的情况下没有问题。 YMMV,但是如果代理的数量不超过几百,那么你应该安全地为每个代理创建一个新的HttpClient实例。如果它更多,我会看看throttling your concurrency并测试它,直到找到一个服务器资源可以跟上的数字。在任何情况下,请确保如果您需要对同一代理进行多次调用,那么您将重新使用HttpClient实例。 ConcurrentDictionary可以用于懒惰地创建和重用这些实例。

© www.soinside.com 2019 - 2024. All rights reserved.