求助:HttpClientHandler中WebProxy的UseProxy属性无法动态切换
动态切换HttpClient代理的问题解决方法
我太懂你这个困扰了——本来想通过复选框轻松切换代理开关,结果发现改了MyProxy.UseProxy之后,HttpClient好像完全没反应,还是按着初始化时的配置来走,对吧?
问题出在哪
你定义的handler是静态变量,它的UseProxy和Proxy属性只会在类第一次加载的时候赋值一次。后续你修改MyProxy.UseProxy,只是改了静态类的属性,并不会自动同步到已经初始化好的handler里——这俩值根本没绑定关系,handler的配置早就固定死了。
最终可行的解决方案(感谢@Milney的思路)
既然静态HttpClientHandler的属性没法动态改,那我们干脆直接准备两个HttpClient实例:一个是带代理配置的,一个是不带的。每次发起请求时,根据当前的开关状态选对应的客户端就行。
先定义好两组handler和client:
// 无代理的配置 private static HttpClientHandler handler = new HttpClientHandler { PreAuthenticate = true, UseDefaultCredentials = false, Proxy = null, UseProxy = false, }; private static readonly HttpClient client = new HttpClient(handler); // 带代理的配置 private static HttpClientHandler handlerWithProxy = new HttpClientHandler { PreAuthenticate = true, UseDefaultCredentials = false, Proxy = new WebProxy($"http://{MyProxy.ProxyHost}:{MyProxy.ProxyPort}", false), UseProxy = true, }; private static readonly HttpClient clientWithProxy = new HttpClient(handlerWithProxy);
然后在发送请求的方法里,根据MyProxy.UseProxy的最新值切换客户端:
private static async Task<JsonDocument> ResponseMessage(HttpRequestMessage request, CancellationToken token) { HttpCompletionOption option = HttpCompletionOption.ResponseHeadersRead; bool useProxy = MyProxy.UseProxy; // 实时选择对应HttpClient发起请求 using (var response = useProxy ? await clientWithProxy.SendAsync(request, option, token).ConfigureAwait(false) : await client.SendAsync(request, option, token).ConfigureAwait(false)) { token.ThrowIfCancellationRequested(); using (var contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) { var json = await ParseJsonFromStream(contentStream); if (!response.IsSuccessStatusCode && json != null) { throw new InvalidDataException($"Error occured: {ParseError(uri, json)}"); } return json; } } }
这样每次请求都会根据当前的代理开关状态选择对应的客户端,完美实现动态切换的需求。
内容的提问来源于stack exchange,提问作者zacky
相关产品推荐
相关产品推荐

