从数据库读取IP调用Ping.SendAsync返回空引发NullReferenceException求助
问题根源
- 从数据库读取的
ip_address字段可能存在DBNull、空字符串、前后冗余空格、非法IP格式等无效值,这些值传入Ping.SendAsync时会导致Ping操作失败,此时PingCompletedEventArgs.Reply属性为null,访问null的Address属性就会抛出NullReferenceException。 - 原有代码没有对Ping返回结果做非空校验,也没有过滤数据库读取的无效IP。
修复步骤
1. 过滤数据库读取的无效IP
修改getNetAddress方法中的读取逻辑,仅添加合法的IP地址到列表:
public static List<string> getNetAddress() { List<string> addr = new List<string>(); string connetionString = @"Data Source=localhost;Initial Catalog=AlarmsDB;Persist Security Info=True;User ID=sa;Password=123456"; using (SqlConnection myConnection = new SqlConnection(connetionString)) { string oString = "Select ip_address from Networks"; SqlCommand oCmd = new SqlCommand(oString, myConnection); myConnection.Open(); using (SqlDataReader oReader = oCmd.ExecuteReader()) { int ipColIndex = oReader.GetOrdinal("ip_address"); while (oReader.Read()) { // 过滤DBNull if (oReader.IsDBNull(ipColIndex)) continue; string ipRaw = oReader[ipColIndex].ToString().Trim(); // 过滤空值和非法IP格式 if (string.IsNullOrWhiteSpace(ipRaw) || !System.Net.IPAddress.TryParse(ipRaw, out _)) continue; addr.Add(ipRaw); } myConnection.Close(); } } return addr; }
2. 增加Ping结果非空校验
修改结果遍历逻辑,避免访问null对象属性:
foreach (var pingTask in pingTasks) { var reply = pingTask.Result; if (reply != null) { Console.WriteLine(reply.Address + "\t" + reply.Status); if (reply.Status != IPStatus.Success) { // 处理Ping失败逻辑 } } else { Console.WriteLine("Ping请求无有效返回结果"); } }
可选:优化异步Ping方法的异常处理
完善PingAsync方法,处理Ping过程中的异常场景:
static Task<PingReply> PingAsync(string address) { var tcs = new TaskCompletionSource<PingReply>(); Ping ping = new Ping(); ping.PingCompleted += (obj, sender) => { if (sender.Error != null) { tcs.SetException(sender.Error); } else if (sender.Reply != null) { tcs.SetResult(sender.Reply); } else { tcs.SetException(new InvalidOperationException("Ping操作无返回结果")); } ping.Dispose(); }; ping.SendAsync(address, 1000, new object()); // 建议增加超时时间,避免长时间等待 return tcs.Task; }
内容的提问来源于stack exchange,提问作者Hamid Mousavi
相关产品推荐
相关产品推荐

