为什么 WhenAll 无限期地等待多个 ping?
Why WhenAll waits indefinetely with multiple pings?
我的应用程序需要 ping 网络中所有可能的 IP 地址。由于 IP 列表很大(大约 4000 个条目),我决定异步执行 ping 以加快进程。我编写的代码最初似乎工作正常,但不知何故,当我昨天尝试它时,它不再按预期工作(可能是在一些 .NET 更新之后?我真的不知道)。
我的代码是这样工作的:我从 IP 地址列表创建了一个任务列表(每个 IP 一个),然后将任务列表传递给 WhenAll 以等待所有 ping 请求完成。问题是有时 WhenAll 会无限期地等待(我用调试器检查过,我看到一些传递给 WhenAll 的任务总是保持在“等待激活”状态)。奇怪的是,有时(3 次测试中大约有 2 次)它按预期工作并且所有任务都完成。
这是我使用的代码:
public static async Task<List<PingReply>> PingAsync(List<IPAddress> ips, int timeout)
{
var pingTasks = ips.Select(ip =>
{
using (Ping ping = new Ping())
{
return ping.SendPingAsync(ip, timeout);
}
});
var results = await Task.WhenAll(pingTasks);
return results.ToList();
}
有什么问题可以提示吗?
问题可能是您在从 SendPingAsync
返回的 Task
完成之前处理 ping
。这将是激烈的,这可能解释了为什么你会看到这种情况不可预测地发生。
在处理 ping
之前尝试等待 Task
:
public static async Task<List<PingReply>> PingAsync(List<IPAddress> ips, int timeout)
{
var pingTasks = ips.Select(async ip =>
{
using (Ping ping = new Ping())
{
return await ping.SendPingAsync(ip, timeout);
}
});
var results = await Task.WhenAll(pingTasks);
return results.ToList();
}
我的应用程序需要 ping 网络中所有可能的 IP 地址。由于 IP 列表很大(大约 4000 个条目),我决定异步执行 ping 以加快进程。我编写的代码最初似乎工作正常,但不知何故,当我昨天尝试它时,它不再按预期工作(可能是在一些 .NET 更新之后?我真的不知道)。
我的代码是这样工作的:我从 IP 地址列表创建了一个任务列表(每个 IP 一个),然后将任务列表传递给 WhenAll 以等待所有 ping 请求完成。问题是有时 WhenAll 会无限期地等待(我用调试器检查过,我看到一些传递给 WhenAll 的任务总是保持在“等待激活”状态)。奇怪的是,有时(3 次测试中大约有 2 次)它按预期工作并且所有任务都完成。
这是我使用的代码:
public static async Task<List<PingReply>> PingAsync(List<IPAddress> ips, int timeout)
{
var pingTasks = ips.Select(ip =>
{
using (Ping ping = new Ping())
{
return ping.SendPingAsync(ip, timeout);
}
});
var results = await Task.WhenAll(pingTasks);
return results.ToList();
}
有什么问题可以提示吗?
问题可能是您在从 SendPingAsync
返回的 Task
完成之前处理 ping
。这将是激烈的,这可能解释了为什么你会看到这种情况不可预测地发生。
在处理 ping
之前尝试等待 Task
:
public static async Task<List<PingReply>> PingAsync(List<IPAddress> ips, int timeout)
{
var pingTasks = ips.Select(async ip =>
{
using (Ping ping = new Ping())
{
return await ping.SendPingAsync(ip, timeout);
}
});
var results = await Task.WhenAll(pingTasks);
return results.ToList();
}