为什么 WhenAll 无限等待多个 ping?

Ori*_*Ori 2 .net c# multithreading ping

我的应用程序需要 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();
     }
Run Code Online (Sandbox Code Playgroud)

关于问题可能是什么的任何提示?

can*_*on7 5

问题可能是您在从可能完成返回ping之前处理。这将是快速的,这可能解释了为什么您会看到这种情况出乎意料地发生。TaskSendPingAsync

Task在处理之前尝试等待ping

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();
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这肯定是问题所在,因为现在它似乎总是工作正常。正如你提到的,这也解释了我的奇怪行为。 (2认同)