WPF程序使用SqlDependencyEx监控数据时网络中断恢复后如何重启监听?
解决方案
1. 网络状态检测方案
你可以二选一或者组合使用以下两种检测方式:
- 系统级网络状态监听
调用NetworkChange.NetworkAvailabilityChanged事件监听Windows全局网络状态变动,系统层面的通知延迟低,无需自行轮询。注意该事件仅代表本机网络正常,无法保证SQL服务器的连通性,触发后需要额外做SQL连通性校验避免误判。 - 定向SQL连通性轮询
当检测到SqlDependencyEx监听失效后,启动低频次后台定时器(建议间隔15~60秒,根据业务需求调整),每次执行轻量SQL查询SELECT 1做连通性校验,查询执行成功即可判定网络和数据库服务已经恢复,停止定时器执行后续恢复逻辑。校验逻辑需要设置3~5秒的超时时间,避免长时间阻塞后台线程。
2. 恢复后的处理逻辑
检测到连通性恢复后按以下顺序执行操作,避免出现资源泄漏或者数据遗漏:
- 调用旧
SqlDependencyEx实例的Dispose()方法,清理残留的事件注册、数据库连接资源,避免重复注册问题 - 重新实例化
SqlDependencyEx,重新绑定数据变更事件监听 - 通过linq2sql重新拉取全量最新数据刷新视图,补齐断网期间未同步的所有数据变更
- 增加23次的失败重试机制,间隔35秒执行一次,避免网络刚恢复时的抖动导致重启监听失败
参考代码示例
// 初始化时注册系统网络状态监听 NetworkChange.NetworkAvailabilityChanged += OnNetworkStateChanged; // 注册SqlDependencyEx的错误事件,监听异常断开 sqlDependency.Error += OnSqlDependencyError; private bool _isListeningValid = true; private void OnSqlDependencyError(object sender, SqlDependencyExErrorEventArgs e) { _isListeningValid = false; // 可选:UI提示数据同步已中断 } private void OnNetworkStateChanged(object sender, NetworkAvailabilityEventArgs e) { // 只有当前监听失效、且网络恢复时才执行校验 if (e.IsAvailable && !_isListeningValid) { Task.Run(() => { if (CheckSqlConnection()) { RestartSqlDependency(); RefreshViewData(); _isListeningValid = true; } }); } } // 数据库连通性校验 private bool CheckSqlConnection() { try { using var conn = new SqlConnection(YourConnectionString); conn.Open(); using var cmd = new SqlCommand("SELECT 1", conn); cmd.CommandTimeout = 3; cmd.ExecuteScalar(); return true; } catch { return false; } } // 重启SqlDependencyEx监听 private void RestartSqlDependency() { _oldSqlDependency.Dispose(); _oldSqlDependency = new SqlDependencyEx(YourConnectionString, DbName, TableName); _oldSqlDependency.TableChanged += OnTableDataChanged; _oldSqlDependency.Start(); }
优化建议
- 无需在程序正常运行时执行连通性校验,只有
SqlDependencyEx报错断开后再启动检测逻辑,减少资源消耗 - 网络中断时可以在UI上增加可视化提示,告知用户当前数据非实时,重连后会自动刷新,提升使用体验
内容的提问来源于stack exchange,提问作者Volpad
相关产品推荐
相关产品推荐

