use*_*558 6 c# multithreading httpclient socks proxies
我需要创建一个发出请求(发布、获取等)的多线程应用程序,为此我选择了Httpclient.
默认情况下它不支持 Socks 代理。所以我发现Sockshandler(https://github.com/extremecodetv/SocksSharp)可以用来代替基本的 HttpClientHandler。它允许我使用袜子。
但我有一个问题。我的所有请求都应该通过我从互联网解析的不同代理发送。但 httpclient 处理程序不支持动态更改代理。如果我没有有效的代理,我需要重新创建一个httclient,这没问题,但是如果我有200个线程,则需要大量的cpu。那么这种情况我该怎么办呢?
第二个问题。我发现这篇文章(https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/HttpClient )讨论了作为单个实例使用以获得更好的性能,但在多线程程序中这是不可能的。在这种情况下哪种方式更好?
谢谢帮助
httpclient 处理程序不支持动态更改代理。
我不确定这在技术上是否正确。代理是一个读/写属性,因此我相信您可以更改它(除非这会导致运行时错误......说实话,我实际上并没有尝试过)。
更新:我现在已经尝试过了,你的断言在技术上是正确的。在下面的示例中,更新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,并且在返回响应之前不会消耗任何线程。
第二个问题。我发现这篇文章...
这绝对是您需要注意的事情。但是,即使您可以HttpClient为每个请求设置不同的代理,底层网络堆栈仍然需要为每个代理打开一个套接字,因此就套接字耗尽问题而言,您不会比每个代理的实例获得任何好处。
最佳解决方案取决于您在这里讨论的代理数量。在文章中,作者描述了当服务器打开大约 4000-5000 个打开套接字时遇到问题,而大约 400 个或更少时没有问题。YMMV,但如果代理的数量不超过几百,您应该可以安全地HttpClient为每个代理创建一个新实例。如果更多,我会考虑限制并发并对其进行测试,直到找到服务器资源可以跟上的数字。无论如何,请确保如果您需要对同一代理进行多次调用,则可以为HttpClient它们重复使用实例。AConcurrentDictionary对于延迟创建和重用这些实例可能很有用。