如何通过PingAsync同时ping多个IP并获取往返时间与状态
多IP异步Ping结果获取问题解决办法
你现在的核心问题是:异步批量ping多个IP时,没法正确对应每个IP的往返时间(RoundtripTime)和状态(Status),而且Update2里的输出代码写错了,导致拿不到正确结果。
问题分析
PingReply对象本身不包含目标IP地址,直接用Task.WhenAll返回的列表,没法知道每个结果对应哪个IP。- Update2的循环里,
replies.Select(r => r.RoundtripTime).ToString()是把整个结果序列转成字符串(输出的是类似System.Linq.Enumerable+SelectListIterator...的无效内容),而不是获取当前遍历项的属性值。
修正后的完整代码
1. 改进批量Ping方法(绑定IP与结果)
public static string[] addresses = { "10.92.114.73", "10.92.114.74", "10.92.114.75" }; // 返回带IP和对应Ping结果的集合 private async Task<List<(string Ip, PingReply Reply)>> Pinger2() { // 每个任务绑定IP和对应的PingReply var tasks = addresses.Select(async ip => (Ip: ip, Reply: await new Ping().SendPingAsync(ip, 2000))); // 等待所有任务完成 var results = await Task.WhenAll(tasks); return results.ToList(); }
2. 调用并正确输出结果
// 调用批量Ping方法 var pingResults = await Pinger2(); // 遍历每个结果,输出IP、往返时间和状态 foreach (var result in pingResults) { TagService.log_Win.AppendLine( $"Pinged {result.Ip} | 往返时间: {result.Reply.RoundtripTime}ms | 状态: {result.Reply.Status}" ); }
关键改动说明
- 绑定IP与结果:用值元组
(string Ip, PingReply Reply)把目标IP和对应的PingReply绑定,遍历的时候能明确知道每个结果属于哪个IP。 - 正确输出属性:循环中直接访问当前项的
result.Reply.RoundtripTime和result.Reply.Status,而不是错误地再次调用replies.Select。
额外优化(可选)
如果需要像Code1那样对每个IP ping多次(比如4次),可以修改批量Ping方法,让每个IP发起多次ping任务:
private async Task<List<(string Ip, int PingCount, PingReply Reply)>> PingerMultipleTimes() { var timesToPing = 4; // 每个IP生成timesToPing个任务,同时记录ping次数 var tasks = addresses.SelectMany(ip => Enumerable.Range(1, timesToPing).Select(async count => (Ip: ip, PingCount: count, Reply: await new Ping().SendPingAsync(ip, 2000)))); var results = await Task.WhenAll(tasks); return results.ToList(); }
调用输出:
var multipleResults = await PingerMultipleTimes(); foreach (var result in multipleResults) { TagService.log_Win.AppendLine( $"Pinged {result.Ip} 第{result.PingCount}次 | 往返时间: {result.Reply.RoundtripTime}ms | 状态: {result.Reply.Status}" ); }
内容的提问来源于stack exchange,提问作者Mdarende
相关产品推荐
相关产品推荐

