并行 Ping 多个 IP 地址 - C#

Ping multiple IP Addresses in parallel - C#

我创建了一个应用程序来同时 ping 网络中的多个特定 IP 地址,如果 ping 成功则显示绿色 PictureBox,如果失败则显示红色 PictureBox。为此,我使用了这段代码:

private void button1_Click(object sender, EventArgs e)
{
    DataTable pingResults = new DataTable();
    pingResults.Columns.AddRange(new DataColumn[] {
                new DataColumn("IP", typeof(string)),
                new DataColumn("Message",typeof(string))});
    try
    {
        pingResults.Clear();
        List<string> ipAddress = new List<string>();
        ipAddress.Add("10.100.1.1");
        ipAddress.Add("10.100.1.2");
        ipAddress.Add("10.100.1.100");

        List<PictureBox> pictureBoxList = new List<PictureBox>();

        for (int i = 1; i < 4; i++)
        {
            pictureBoxList.Add((PictureBox)Controls.Find("pictureBox" + i, true)[0]);
        }

        for (int i = 0; i < ipAddress.Count; i++)
        {
            Ping ping = new Ping();
            PingReply pingReply = ping.Send(ipAddress[i].ToString());

            pictureBoxList[i].BackColor = (pingReply.Status == IPStatus.Success) ? Color.Green : Color.Red;

            Thread.Sleep(1000);
        }


    }
    catch (Exception ex)
    {

    }
}

此代码有效,但花费的时间太长。我在 Whosebug 上使用 BackgroundWorker 尝试了很多示例,但我不知道该怎么做

你可以试试Parallel.For,很简单。

Parallel.For(0, ipAddress.Count() - 1, (i, loopState) =>
{
  Ping ping = new Ping();
  PingReply pingReply = ping.Send(ipAddress[i].ToString());
  //for wpf
  Dispatcher.BeginInvoke((Action)delegate()
  {    
    pictureBoxList[i].BackColor = (pingReply.Status == IPStatus.Success) ? Color.Green : Color.Red;    
  });
  //for winform
  SetColor(pictureBoxList[i], pingReply.Status == IPStatus.Success);
});
//for winform delegate
delegate void SafeSetColor(PictureBox pb, bool success);
private void SetColor(PictureBox pb, bool success)
{
 if(pb.InvokeRequired)
 {
   SafeSetColor objSet=new SafeSetColor(SetColor);
   pb.Invoke(objSet,new object[]{pb, success});
 }
 else
 {
   pb.BackColor = (success) ? Color.Green : Color.Red;
 }
}

我找到了解决方案,我使用了 backgroundworker:

DataTable pingResults = new DataTable();

List<string> ipAddress = new List<string>();

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        pingResults.Clear();
        ipAddress.Add("10.100.1.1");
        ipAddress.Add("10.100.1.2");
        ipAddress.Add("10.100.1.3");
        ipAddress.Add("10.100.1.4");
        ipAddress.Add("10.100.1.5");
        ipAddress.Add("10.100.1.100");

        List<PictureBox> pictureBoxList = new List<PictureBox>();

        for (int i = 1; i < 7; i++)
        {
            pictureBoxList.Add((PictureBox)Controls.Find("pictureBox" + i, true)[0]);
        }

        Parallel.For(0, ipAddress.Count(), (i, loopState) =>
        {
            Ping ping = new Ping();
            PingReply pingReply = ping.Send(ipAddress[i].ToString());

            this.BeginInvoke((Action)delegate()
            {
                pictureBoxList[i].BackColor = (pingReply.Status == IPStatus.Success) ? Color.Green : Color.Red;
            });

        });
    }

private void button1_Click(object sender, EventArgs e)
    {
        backgroundWorker1.RunWorkerAsync();
    }