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

WPF网络连接检测异常:Ping抛出Socket/DNS异常及UI不更新问题

问题分析与修复方案

你的代码存在几个核心问题,导致网络状态检测异常、UI更新错误:

  • 颜色逻辑完全颠倒:网络可用时设置深红色(#841c34),无网络时反而设置绿色(#00ff00),和需求完全相反。
  • 异常捕获不完整:IsWebsiteUp_Ping仅捕获SocketException,但DNS解析失败会抛出PingException、Uri格式错误会抛出UriFormatException,未捕获的异常会打断UI更新逻辑。
  • Ping方式不可靠:多数公共服务器(包括Google)会禁用ICMP Ping请求,即使网络正常也会返回失败,导致误判。
  • BrushConverter重复调用且不安全:每次Tick都创建转换器转换颜色,效率低且可能因格式错误抛出异常。

修复后的完整代码

// 预定义画笔,避免重复转换和异常
private readonly SolidColorBrush _onlineBrush = new SolidColorBrush(Colors.Green);
private readonly SolidColorBrush _offlineBrush = new SolidColorBrush(Color.FromRgb(0x84, 0x1C, 0x34));
private DispatcherTimer _networkCheckTimer;
// 复用HttpClient实例,避免频繁创建释放
private readonly HttpClient _httpClient = new HttpClient
{
    Timeout = TimeSpan.FromSeconds(2)
};

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    _networkCheckTimer = new DispatcherTimer
    {
        Interval = TimeSpan.FromSeconds(2)
    };
    _networkCheckTimer.Tick += NetworkCheckTimer_Tick;
    _networkCheckTimer.Start();
}

private async void NetworkCheckTimer_Tick(object sender, object e)
{
    // 避免Timer叠加触发(网络慢时,上一次请求未完成就触发下一次Tick)
    _networkCheckTimer.Stop();
    try
    {
        bool isOnline = await IsNetworkAvailableAsync();
        einternetcoxn.Fill = isOnline ? _onlineBrush : _offlineBrush;
    }
    catch (Exception ex)
    {
        Console.WriteLine($"网络检测异常: {ex.ToString()}");
        einternetcoxn.Fill = _offlineBrush;
    }
    finally
    {
        _networkCheckTimer.Start();
    }
}

private async Task<bool> IsNetworkAvailableAsync()
{
    try
    {
        // 使用HEAD请求检测,比Ping更可靠,且资源占用少
        var response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://www.google.com"));
        // 返回成功状态码即视为网络可用
        return response.IsSuccessStatusCode;
    }
    catch (HttpRequestException)
    {
        return false;
    }
    catch (TaskCanceledException)
    {
        // 请求超时,视为无网络
        return false;
    }
    catch (Exception)
    {
        // 其他所有异常都视为无网络
        return false;
    }
}

// 窗口关闭时释放资源,防止内存泄漏
private void Window_Closed(object sender, EventArgs e)
{
    _networkCheckTimer?.Stop();
    _httpClient?.Dispose();
}

关键修复点说明

  1. 颜色逻辑修正:用预定义画笔直接赋值,确保网络可用时显示绿色,无网络时显示红色。
  2. 完整异常处理:覆盖所有可能的网络异常场景,确保任何错误都能触发UI更新为离线状态。
  3. 替换检测方式:用HttpClient的HEAD请求替代Ping,避免服务器禁用ICMP导致的误判,同时HEAD请求仅获取响应头,比GET请求更高效。
  4. Timer防叠加:Tick事件中先停止Timer,请求完成后重启,避免多请求并发执行。
  5. 资源复用与释放:复用HttpClient实例降低开销,窗口关闭时释放资源避免内存泄漏。

静态IP配置场景说明

当你配置静态IP(192.168.192.90)且网关设为自身IP时,网络本身不可达,修复后的代码会正确捕获请求失败,将UI设为红色,符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 20:35:24