0

我是这个线程世界的新手。我看到了一堆关于线程的教程,但我仍然觉得很难以我想要的方式使用。我想要的是在我得到 Ping 结果后立即更新标签。下面的代码运行良好,除了它在返回所有 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;
        }
    }
}
4

2 回答 2

1

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

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

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

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

于 2013-01-16T15:11:57.487 回答
1

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

  • 使用委托函数作为主 gui 的回调方法
  • 您可以将结果存储在任何地方并通过存储在 gui 中的计时器不断检查它们
  • 最后你可以使用BeginInvoke方法

祝你好运!

于 2013-01-16T14:47:40.757 回答