所以,有一个服务器,你需要不断地、异步地知道它的状态......
这样试了,不行
Thread pingThread = new Thread(_client_PingServer);
pingThread.Start();
private void _client_PingServer()
{
try
{
System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
System.Net.NetworkInformation.PingReply pingReply = ping.Send(settingsControl1.txtIPAddress.Text);
if (pingReply.RoundtripTime <= 70 && pingReply.RoundtripTime >= 1)
{
labelServerStatus.ForeColor = System.Drawing.Color.Green;
}
else if (pingReply.RoundtripTime >= 70 && pingReply.RoundtripTime <= 120)
{
labelServerStatus.ForeColor = System.Drawing.Color.Orange;
}
else if (pingReply.RoundtripTime >= 120)
{
labelServerStatus.ForeColor = System.Drawing.Color.Red;
}
else if (pingReply.RoundtripTime == 0)
{
labelServerStatus.Text = @"Offline";
}
if (pingReply.RoundtripTime != 0)
{
labelServerStatus.Text = pingReply.RoundtripTime.ToString();
}
}
catch (PingException)
{
labelServerStatus.ForeColor = System.Drawing.Color.Red;
labelServerStatus.Text = @"Offline";
}
}
你的想法?
首先,让我们弄清楚为什么它不起作用。首先,因为您正在从另一个线程访问 UI 控件的属性。这是不可能的,UI 元素只能从创建和处理它们的线程中获得,因为 他们需要收听系统消息并响应用户操作。
第二个原因是你的方法代码,即使修复之前的错误不是循环的,所以它只会执行一次是有道理的。
定期执行某些操作的最简单方法是使用计时器,因为 一个简单的循环在这里不起作用。
该类
Ping
具有执行相同操作的异步Ping.SendAsync方法。就像您使用的常规一样,Ping.Send
仅用于异步执行。主机不可用时 Windows 的标准 ping 超时为 4 秒。(证明),所以如果重要,您将不得不选择另一个重载Ping.SendAsync
,允许您在调用方法时在参数中指定超时值。现在让我们将所有内容放在一起以获得所需的结果。对于 WinForms 应用程序,我们将使用System.Windows.Forms.Timer作为计时器,因为 一方面,我们需要能够使用控件的属性,特别是这个计时器在 UI 线程中执行处理程序,另一方面,
SendAsync
我们只需要正确调用它,因为 它已经使用异步。添加一个计时器并设置它的参数在代码示例中有很好的记录,所以在这里我将只展示Timer.Tick事件处理程序,它将完成所有工作。
它仍然使用此方法订阅事件
Tick
并激活计时器,例如,在成功首次连接到服务器之后。如您所见,代码中的更改很少,但一切正常。