我同意Todd Menier的回答。但是,如果您使用 .Net 核心,我建议您阅读这篇文章以及微软所说的这篇文章:
为每个请求实例化一个 HttpClient 类将耗尽重负载下可用的套接字数量。该问题将导致 SocketException 错误。
这很可悲,但他们提供了一个解决方案:
为了解决上述问题并简化 HttpClient 实例的管理,.NET Core 2.1 引入了一个新的 HttpClientFactory,它还可以通过将 Polly 与其集成来实现弹性 HTTP 调用。
我查看了IHttpClientFactory
摘要块并看到:
每次调用 System.Net.Http.IHttpClientFactory.CreateClient(System.String)都保证返回一个新的 System.Net.Http.HttpClient 实例。调用者可以无限期地缓存返回的 System.Net.Http.HttpClient 实例,或者将其使用包围在 using 块中,以便在需要时对其进行处理。默认 System.Net.Http.IHttpClientFactory实现可能会缓存底层 System.Net.Http.HttpMessageHandler 实例以提高性能。
调用者还可以根据需要自由地改变返回的 System.Net.Http.HttpClient 实例的公共属性。
我们来看图片
IHttpClientFactory
实现注入某些服务(CatalogueService 或您制作的任何东西),然后在每次需要发出请求时HttpClient
通过实例化(您甚至可以将其包装成块),但将缓存在某种连接池中。IHttpClientFactory
using(...)
HttpMessageHandler
因此,您可以根据HttpClientFactory
需要创建许多HttpClient
实例并在拨打电话之前设置代理。如果有帮助,我会很高兴。
更新:
我试过了,它实际上不是你需要的。您可以IHttpClientFactory
像这样实现自己的:
public class Program
{
public interface IHttpClientFactory
{
HttpClient CreateClientWithProxy(IWebProxy webProxy);
}
internal class HttpClientFactory : IHttpClientFactory
{
private readonly Func<HttpClientHandler> makeHandler;
public HttpClientFactory(Func<HttpClientHandler> makeHandler)
{
this.makeHandler = makeHandler;
}
public HttpClient CreateClientWithProxy(IWebProxy webProxy)
{
var handler = this.makeHandler();
handler.Proxy = webProxy;
return new HttpClient(handler, true);
}
}
internal class CachedHttpClientFactory : IHttpClientFactory
{
private readonly IHttpClientFactory httpClientFactory;
private readonly Dictionary<int, HttpClient> cache = new Dictionary<int, HttpClient>();
public CachedHttpClientFactory(IHttpClientFactory httpClientFactory)
{
this.httpClientFactory = httpClientFactory;
}
public HttpClient CreateClientWithProxy(IWebProxy webProxy)
{
var key = webProxy.GetHashCode();
lock (this.cache)
{
if (this.cache.ContainsKey(key))
{
return this.cache[key];
}
var result = this.httpClientFactory.CreateClientWithProxy(webProxy);
this.cache.Add(key, result);
return result;
}
}
}
public static void Main(string[] args)
{
var httpClientFactory = new HttpClientFactory(() => new HttpClientHandler
{
UseCookies = true,
UseDefaultCredentials = true,
});
var cachedhttpClientFactory = new CachedHttpClientFactory(httpClientFactory);
var proxies = new[] {
new WebProxy()
{
Address = new Uri("https://contoso.com"),
},
new WebProxy()
{
Address = new Uri("https://microsoft.com"),
},
};
foreach (var item in proxies)
{
var client = cachedhttpClientFactory.CreateClientWithProxy(item);
client.GetAsync("http://someAddress.com");
}
}
}
但要小心可能占用池中所有连接的大量 WebProxy 集合。