使用线程检查与主机的网络连接时更新标签

时间:2013-01-16 14:38:42

标签: c# winforms multithreading

我是这个线程世界的新手。我看到一些关于线程的教程,但我仍然觉得很难用我想要的方式。我想要的是在得到Ping结果后立即更新Label。下面的代码运行良好,除了它返回所有ping结果后一次更新所有标签。我认为使用Thread可以帮助我解决这个问题。

for (int i = 0; i < lblPings.Count; i++)
{
    Ping x = new Ping();
    if (txtTo[i].Text.Length > 0)
    {
        PingReply reply = x.Send(IPAddress.Parse(txtTo[i].Text)); 
        if (reply.Status == IPStatus.Success)
        {
            lblPings[i].Text = reply.RoundtripTime.ToString() + "ms";
            lblPings[i].ForeColor = Color.Blue;
        }
        else //if host is not reachable.
        {
            lblPings[i].Text = "Failed";
            lblPings[i].ForeColor = Color.Red;
        }
    }
}

2 个答案:

答案 0 :(得分:1)

您可以使用无限期ping主机的线程并将结果存储在任何位置。问题是线程无法修改GUI的任何内容,但有三种可能的解决方案:

  • 使用delegate函数作为主gui的回调方法
  • 您可以将结果存储在任何地方,并从存储在gui
  • 中的计时器中不断检查它们
  • 最后,您可以使用BeginInvoke方法
祝你好运!

答案 1 :(得分:1)

这将有助于了解幕后发生的事情。

在控件上设置属性时,告诉该控件重绘自身。相反,会发生两件事:您更改控件将在以后重绘时使用的数据,并向窗口系统发送一条消息,表明此控件已过期。您现在必须等待窗口系统返回并在任何更新发生之前重新绘制控件。

这里的问题是任何重新绘制都发生在事件处理程序和其他普通代码使用的相同的线程上。这意味着在整个方法完成并且该线程上的控制流返回到窗口系统之前,您无法使用您认为的正常代码更新控件。

有几种不同的方法可以解决这个问题,例如DoEvents或Invoke,但我认为大多数时候最适合Winforms应用程序的方法是使用BackgroundWorker控件。