networkinterface.getisnetworkavailable() 不可靠,仅检测网卡启用状态而非物理连接;推荐用 wmi 查询 win32_networkadapter 的 netconnectionstatus 字段(2=已连接,0=未连接)实现秒级准确判断。

用 NetworkInterface.GetIsNetworkAvailable() 判断“有网”不靠谱
这个函数只看有没有任意一个非环回、已启动的网卡,插着坏网线、网线连着断电交换机、甚至网卡驱动假死,它都可能返回 true。它不是检测物理连接,而是检测系统认为“网络栈可用”。真实场景下,用户拔网线后几秒内该函数仍返回 true,根本没法做及时提醒。
实操建议:
- 别单独依赖
NetworkInterface.GetIsNetworkAvailable()做插拔判断 - 它适合做粗筛(比如启动时快速跳过离线逻辑),但不能用于实时状态监听
- 若配合轮询,间隔至少 500ms 以上,太频繁会白占 CPU 且毫无意义
监听 NetworkChange.NetworkAvailabilityChanged 事件的坑
这个事件确实能捕获网卡启停,但它的触发条件很“重”:只有当接口状态从“已连接”变成“已断开”(或反向),且系统判定该接口不再参与路由时才触发。而网线刚拔掉时,Windows 往往维持旧状态几秒到十几秒(取决于驱动和 NDIS 层缓存),期间事件完全不 firing。
常见错误现象:
- 拔网线后等 8 秒才收到
NetworkAvailabilityChanged事件 - 笔记本合盖再打开,事件没触发(因为接口是“休眠”而非“断开”)
- 虚拟网卡(如 VMware、Docker)状态变化也会触发,干扰主物理网卡判断
实操建议:
- 订阅事件后,立刻调用一次
NetworkInterface.GetIsNetworkAvailable()做初始状态快照 - 在事件回调里,必须遍历
NetworkInterface.GetAllNetworkInterfaces(),检查目标网卡(比如Name含"Ethernet"或OperationalStatus == OperationalStatus.Up)的真实状态,不能只信事件参数 - 避免在 UI 线程直接更新控件——事件回调不在 UI 线程,需用
Invoke或Dispatcher.BeginInvoke
用 WMI 查询 Win32_NetworkAdapter 的 NetConnectionStatus
这才是真正对应物理插拔的指标:NetConnectionStatus == 2 表示“已连接”,== 0 表示“未连接”(注意不是断开,是物理层无链路)。它绕过了 TCP/IP 栈,直读网卡 NDIS 状态,响应通常在 1–3 秒内,比 .NET 自带 API 更准。
使用场景:
- 需要秒级响应插拔,且能接受少量 WMI 查询开销
- 部署环境允许启用 WMI 服务(默认 Windows 都开)
- 目标机器不是 Nano Server 或极简容器环境(WMI 不可用)
实操建议:
- 用
ManagementEventWatcher订阅Win32_NetworkAdapter的InstanceModificationEvent,过滤WHERE TargetInstance.NetConnectionID LIKE '%Ethernet%' - 重点看
TargetInstance.NetConnectionStatus字段值,不是PhysicalAdapter或AdapterType - 首次查询先用
ManagementObjectSearcher拉一次全量,避免漏掉初始状态 - 别用
SELECT *,只查NetConnectionID, NetConnectionStatus, Name,减少序列化开销
为什么不能只靠 Ping 或 HTTP 请求保活
Ping 发包成功只说明三层可达,HTTP 成功只说明应用层通;网线插着但路由器崩了、DNS 挂了、防火墙拦了 ICMP,这些都会误报“断网”。反过来,网线刚插上但 DHCP 还没拿到地址、ARP 表还没刷,Ping 就会失败,造成“已插线却提示断开”的错觉。
性能与兼容性影响:
- 高频
Ping(如每秒一次)会显著增加网络负载,某些嵌入式设备网卡会发烫或丢包 - .NET 6+ 的
Ping.SendPingAsync()默认超时 5 秒,卡主线程风险高;老版本Ping.Send()是同步阻塞,更危险 - 企业内网常禁 ICMP,
Ping直接失效,而NetConnectionStatus不受影响
真要用保活探测,必须满足两个条件:目标地址是网关(不是公网域名),且超时设为 ≤800ms;否则不如不用。
物理链路状态这事,操作系统底层比任何应用层探测都诚实。别绕远路,老实用 WMI 查 NetConnectionStatus,再辅以网卡名过滤,最稳。










