代码之家  ›  专栏  ›  技术社区  ›  user48202

使用Ping映射活动IP的线程问题-C#

  •  1
  • user48202  · 技术社区  · 16 年前

    提前谢谢。

            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            count = 0;
            for (int j = 1; j < 255; j++)
                for (int i = 1; i < 255; i++)
                {
                    Ping ping = new Ping();
                    PingReply pingreply = ping.Send(IPAddress.Parse(locip[0] + "." + locip[1] + "." + j + "." + i));
    
                    if (pingreply.Status == IPStatus.Success)
                    {
                        status = "o";
                        repAddress = pingreply.Address.ToString(); ;
                        repRoundtrip = pingreply.RoundtripTime.ToString();
                        repTTL = pingreply.Options.Ttl.ToString();
                        repBuffer = pingreply.Buffer.Length.ToString();
    
                        string[] lineBuffer = { status, repAddress, repRoundtrip, repTTL, repBuffer };
                        ipList.Rows.Add(lineBuffer);
                        count += 1;
                        progressBar.Value += 1;
                    }
    
                }
    
    
        }
    
    3 回复  |  直到 16 年前
        1
  •  1
  •   JaredPar    16 年前

    问题的一部分是您正在从后台线程直接访问UI元素。田野 progressBar 可能是一个UI进度条控件,只能从UI线程安全访问。必须使用对.Invoke的调用从UI线程设置此值。

    progressBar.Invoke(new MethodInvoker(UpdateProgressBarbyOne));
    ...
    
    private void UpdateProgressBarByOne() {
      progressBar.Value += 1;  
    }
    
        2
  •  2
  •   Alex LE    16 年前

    无法从backgroundWorker1“DoWork”事件直接访问progressBar1(或任何其他UI元素),必须使用backgroundWorker1.ProgressChanged方法并处理ProgressChanged事件:

    // instead of progressBar.Value += 1
    // use the following
    
    const int total = 254 * 254;
    backgroundWorker1.ReportProgress(count / total);
    

    WorkerReportsProgress应指定为true 并且progress事件更改为以下方法

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        // assuming the Minimum = 0 and Maximum = 100 on progressBar
        progressBar.Value = e.ProgressPercentage;
    }
    
        3
  •  0
  •   user220583 user220583    16 年前

    因此,当我开始学习如何制作响应性应用程序时,我遇到了函数:Application.DoEvents()

    (http://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents.aspx)

    i、 e.在点击事件处理程序中

    count = 0;
            for (int j = 1; j < 255; j++)
                for (int i = 1; i < 255; i++)
                {
                    Ping ping = new Ping();
                    PingReply pingreply = ping.Send(IPAddress.Parse(locip[0] + "." + locip[1] + "." + j + "." + i));
    
                    if (pingreply.Status == IPStatus.Success)
                    {
                        status = "o";
                        repAddress = pingreply.Address.ToString(); ;
                        repRoundtrip = pingreply.RoundtripTime.ToString();
                        repTTL = pingreply.Options.Ttl.ToString();
                        repBuffer = pingreply.Buffer.Length.ToString();
    
                        string[] lineBuffer = { status, repAddress, repRoundtrip, repTTL, repBuffer };
                        ipList.Rows.Add(lineBuffer);
                        count += 1;
                        progressBar.Value += 1;
                    }
                    Application.DoEvents(); //but not too often.
                }
    

    现在,这是回到前网络时代,它一直存在到现在,但是,这不是你应该掉以轻心的事情。如果您单击窗体上的另一个按钮,它将启动另一个线程,该线程将尝试执行,如果您不小心,将导致窗体上出现线程异常。一些开发人员会告诉您不使用此功能,但既然您刚开始使用,我会说尝试一下:)

    根据应用程序的不同,我可能不会使用此方法。相反,我要做的是创建几个处理“序列”;系统拥有的每个cpu核心一个。我将要扫描的IP添加到队列对象,然后启动2到4个线程实例( http://msdn.microsoft.com/en-us/library/system.threading.thread.aspx http://msdn.microsoft.com/en-us/library/ms171728.aspx )在我的表单上,我会相应地更新UI的信息。

    线程是有趣的,伙计:)随着时间的推移,你会发现你可以使用MSMQ来制作一个系统,该系统使用其他计算机的多核来完成诸如图像处理(或带有pa的东西……)

    推荐文章