我正在制作一个非常简单的程序。我想要它,以便当我点击btnPing时,它会每1秒向google.com发送一次ping,并以毫秒为单位返回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);
}
}
答案 0 :(得分:3)
您正在UI线程上输入无限循环。 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();
}
答案 1 :(得分:3)
原因是因为你的循环阻塞 UI,而后者又无法更新自身并且似乎被冻结(实际上程序正在循环中执行ping)。您必须在单独的线程中以异步方式运行 (即与UI代码并行)。要开始使用,请参阅BackgroundWorker
class提供的示例。
答案 2 :(得分:0)
由于你的while循环以不间断的方式执行,你在屏幕上看不到任何东西,感觉就像屏幕冻结一样。您可以使用计时器而不是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");
}