如何在c#中等待异步ping的加载完成?

本文关键字:加载 ping 异步 等待 | 更新日期: 2023-09-27 18:02:05

我使用下面的代码来启动异步ping的加载。我还有一个由PingCompletedEventHandler调用的函数,该函数将成功ping的地址添加到列表中以供稍后使用。

我想知道如何有可能调用一个函数一旦所有的ping线程已经完成?

    public static void PingRange(IPRange range)
    {
        foreach (IPAddress ip in range.GetAllIP())
        {
            // Create Pinger
            AutoResetEvent waiter = new AutoResetEvent(false);
            Ping pingSender = new Ping();
            pingSender.PingCompleted += new PingCompletedEventHandler(pingSender_PingCompleted);
            // Create a 32 byte data buffer
            string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
            byte[] buffer = Encoding.ASCII.GetBytes(data);
            // Wait 4 seconds for a reply
            int timeout = 4000;
            PingOptions options = new PingOptions(64, true);
            pingSender.SendAsync(ip, timeout, buffer, options, waiter);
            PingStartCount++;
        }
    }

如何在c#中等待异步ping的加载完成?

如果您使用的是。net 4.0,这是相当容易的。您可以使用CountdownEvent类来代替PingStartCount计数器和waiter事件。CountdownEvent将完成两者的工作。

public static void PingRange(IPRange range)
{            
    var finished = new CountdownEvent(1);
    foreach (IPAddress ip in range.GetAllIP())
    {
        finished.AddCount(); // Indicate that a new ping is pending
        var pingSender = new Ping();
        pingSender.PingCompleted +=
          (sender, e) =>
          {
            finished.Signal(); // Indicate that this ping is complete
          };
        string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
        byte[] buffer = Encoding.ASCII.GetBytes(data);
        PingOptions options = new PingOptions(64, true);
        pingSender.SendAsync(ip, 4000, buffer, options, waiter);
    }
    finished.Signal(); // Indicate that all pings have been submitted
    finished.Wait(); // Wait for all pings to complete
}

一个简单的解决方案是在pingSender_PingCompleted事件处理程序中使用PingStartCount变量来跟踪仍然等待完成的ping数(每次调用pingSender_PingCompleted时扣除1)。一旦PingStartCount达到0,你就会收到所有的ping。

然而,这并不能完全证明,因为当计数器达到0时,您可能仍在启动ping的过程中。为了确保这种情况不会发生,在PingRange开始时设置一个简单的bool变量为false,在PingRange结束时设置为true,这样可以检查ping是否仍在发送。