You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Framework HttpClient断网重连后报远程名称无法解析问题排查

场景背景

设备为接入企业代理网络的笔记本,在应用中使用.NET Framework 4.8的HttpClient时,网络连通状态下请求正常;断开网络后抛出The remote name could not be resolved异常,符合预期。

但网络恢复、应用保持运行时,仍持续抛出The remote name could not be resolved异常,同环境下浏览器访问目标地址正常,重启应用后请求恢复正常。以下为整合多份同类异常解决方案编写的最小复现Demo。

问题咨询

是否是.NET底层内部存在缓存机制导致该问题?复现Demo中已实现每次请求新建HttpClient、新建HttpClientHandler、设置ConnectionClose请求头、调整ServicePointManager相关参数,如果确实存在底层缓存,要如何修改配置清除或调整缓存逻辑?

补充说明:在正式业务场景中,使用AddHttpClient<TI,T>方式注册HttpClient服务,对应依赖的服务类并非单例生命周期,仍存在完全相同的故障。

internal class Program
{
    static async Task Main(string[] args)
    {
        var sp = ServicePointManager.FindServicePoint(new Uri("https://www.google.com"));
        sp.SetTcpKeepAlive(false,0,0);
        sp.ConnectionLeaseTimeout = (int)TimeSpan.FromSeconds(15).TotalMilliseconds;

        ServicePointManager.DnsRefreshTimeout = (int)TimeSpan.FromSeconds(15).TotalMilliseconds;

        while (true)
        {
            try
            {
                using (var client = new HttpClient(new HttpClientHandler()))
                {
                    Console.WriteLine("Press Key to try send");
                    Console.ReadKey();

                    var uri = "https://www.google.com";

                    var message = new HttpRequestMessage(HttpMethod.Get, uri);
                    message.Headers.ConnectionClose = true;
                    message.Headers.CacheControl = new CacheControlHeaderValue()
                    {
                        MaxAge = TimeSpan.FromSeconds(1),
                    };

                    var response = await client.SendAsync(message);
                    Console.WriteLine("Success:");
                    Console.WriteLine(await response.Content.ReadAsStringAsync());
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
    }
}
排查进展

进展1

感谢@Lex Li提供的追踪方法,通过查看系统网络追踪日志,发现如下现象:

  • 请求1(网络连通状态):System.Net Verbose: 0 : [25368] Entering ServicePoint#6044116::ServicePoint(myproxyaddress:8080)
  • 请求2(网络断开状态):System.Net Verbose: 0 : [29900] Entering ServicePoint#3507177::ServicePoint(www.google.com:443)
  • 请求3(网络恢复状态):System.Net Information: 0 : [29900] Associating HttpWebRequest#37200859 with ServicePoint#3507177

由此可见网络恢复后请求错误关联了断网时生成的直连ServicePoint实例。
如果将HttpClient和HttpClientHandler的实例化逻辑移到循环外,初始网络正常的场景下重连后可恢复正常;但如果应用启动时就处于断网状态,仍会因为关联错误的ServicePoint实例导致请求失败。初步判断需要在适用场景下显式指定代理配置,避免.NET自动探测代理时缓存错误的连接配置。

进展2

测试验证,显式指定代理地址确实可以解决该问题,可避免.NET自动探测连接路径时出现缓存错误,但硬编码代理配置的方式无法适配代理配置动态变更的场景。验证代码如下:

var handler = new HttpClientHandler()
{
    Proxy = new WebProxy("myproxyadress:8080")
};
var client = new HttpClient(handler);

内容的提问来源于stack exchange,提问作者XWIKO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 00:39:19