While循环使用Ping命令

本文关键字:Ping 命令 循环 While | 更新日期: 2023-09-27 18:15:31

我在编写一个非常简单的程序时遇到了麻烦。我希望当我点击btnPing时,它会每1秒发送一个ping到google.com,并以毫秒为单位返回ping。在我想循环动作之前,它一直运行得很好。在while循环之外,代码可以工作,但需要我每次想发送ping时单击按钮。但是当我将代码放入循环中时,它就冻结了。我试过用for循环和while循环。程序没有返回任何错误。是什么导致我的程序冻结?

Ping pingClass = new Ping();
private void btnPing_Click(object sender, EventArgs e)
{
    while (true)
    {
        PingReply pingReply = pingClass.Send("google.com");
        rtxtPing.Text = rtxtPing.Text + "'r'n" + (pingReply.RoundtripTime.ToString() + "ms");
        System.Threading.Thread.Sleep(1000);
    }
}

While循环使用Ping命令

原因是你的循环阻塞了 UI,而UI又不能更新自己,看起来像是被冻结了(而实际上程序正在循环中执行ping)。你必须在一个单独的线程中异步地运行它(即与UI代码并行)。要开始,请参见BackgroundWorker类提供的示例。

您正在进入UI线程的无限while循环。Sleep是一个阻塞调用,也就是说,它不会"释放"线程来继续做其他工作。

下面是一个使用事件的解决方案:

        public delegate void PingReceivedEventHandler(int time);
        public event PingReceivedEventHandler PingReceived;
        public Form1()
        {
            InitializeComponent();
            PingReceived += new PingReceivedEventHandler(Form1_PingReceived);
        }
        void Form1_PingReceived(int time)
        {
            //do something with val
        }
        private void button1_Click(object sender, EventArgs e)
        {
            (new Thread(() =>
                {
                    while(true)
                    {
                        int time;
                        //get value here
                        PingReceived(time);
                    }
                }
            )).Start();
        }

因为while循环是以不停止的方式执行的,所以你在屏幕上看不到任何东西,感觉屏幕被冻结了。您可以通过使用Timer而不是while循环来获得所需的结果。我已经测试了这段代码,它工作得很好。

将以下代码放入按钮单击事件

private void button2_Click(object sender, EventArgs e)
{         
    Timer timer = new Timer { Interval = 1000, Enabled = true };
    timer.Tick += new EventHandler(PingTest);            
}

添加一个带有ping逻辑的方法,如下所示

public void PingTest(object sender, EventArgs e)
{
    Ping pingClass = new Ping();
    PingReply pingReply = pingClass.Send("google.com");
    rtxtPing.Text = rtxtPing.Text + "'r'n" + (pingReply.RoundtripTime.ToString() + "ms");        
}