【问题标题】:Why WhenAll waits indefinetely with multiple pings?为什么WhenAll无限期地等待多次ping?
【发布时间】:2020-10-28 10:35:58
【问题描述】:

我的应用程序需要 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无论如何,所以您的第二个错误避免了第一个错误...也许这个问题是您没有处理(第二个)new Ping()?我不确定它使用了哪些非托管资源。
  • 对不起,我刚刚看到我混合了我制作的代码的两个版本(我尝试了很多方式)。我将编辑问题以删除不需要的第二个 Ping。但是Task返回后如何正确处理Ping实例呢?
  • 在代码的编辑版本中,您可能在 SendPingAsync 完成之前处置 ping,从而导致不可预测的行为。只需将匿名函数传递给 Select async - async ip =&gt; ... return await ping.SendPingAsync

标签: c# .net multithreading ping


【解决方案1】:

问题可能是您在从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();
}

【讨论】:

  • 您在等待SendPingAsync 时失去了并行性,不是吗?这就是WhenAll的目的
  • 第一个示例无法编译,而第二个示例将失败,因为Ping 类不支持来自同一实例的并发 ping。
  • @Phate01 不。如果我在循环中对ipsawait 进行了循环,那么你是对的,但这是在创建一个async 函数(其中包含@ 987654333@ 和 await),多次调用它,然后一口气等待结果 Tasks
  • @Evk 修复了丢失的return。我不确定并发性,因此需要注意。已删除。
  • 谢谢,这肯定是问题所在,因为现在它似乎总是可以正常工作。正如你所提到的,这也解释了我的奇怪行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-12
  • 1970-01-01
  • 2016-03-08
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多