应用程序滞后于每个计时器滴答

时间:2013-04-08 12:27:27

标签: c# winforms timer

我有一个应用程序会定期ping服务器,以便为您提供连接延迟。根据我的阅读,System.Timers.Timer在与UI的单独线程上运行。

public MainForm()
{
    InitializeComponent();
    _timer = new Timer();
    _timer.Tick += new EventHandler(timer_Tick);
    _timer.Interval = 1000;
    _timer.Start();
}

我有一个NotifyIcon,其中ContextMenu显示此ping的结果。但是我注意到每次计时器滴答时ContextMenu都滞后,我不明白为什么。

编辑:完全忘记添加timer_tick功能

            var selectedServer = Properties.Settings.Default.SelectedServer;
            PingReply reply;
            switch (selectedServer)
            {
                case "NA":
                    reply = _pvpnetClient.Send("64.7.194.1");
                    break;
                case "EUW":
                    reply = _pvpnetClient.Send("95.172.65.1");
                    break;
                case "EUN":
                    reply = _pvpnetClient.Send("66.150.148.1");
                    break;
                default:
                    reply = _pvpnetClient.Send("64.7.194.1");
                    break;
            }

            if (reply == null || reply.Status != IPStatus.Success) return;
            var returnedPing = reply.RoundtripTime;

            LoLPing.Text = @"Server: " + selectedServer + @" - Ping: " + reply.RoundtripTime + @"ms";
            PingText.Text = @"Ping: " + reply.RoundtripTime + @"ms";
            if (returnedPing < 120f)
            {
                LoLPing.Icon = Properties.Resources.GreenIcon;
            }
            else if (returnedPing > 120f && returnedPing < 200)
            {
                LoLPing.Icon = Properties.Resources.YellowIcon;
            }
            else
            {
                LoLPing.Icon = Properties.Resources.RedIcon;
            }

2 个答案:

答案 0 :(得分:2)

http://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.100).aspx

“基于服务器的Timer设计用于多线程环境中的工作线程。”

它不会自动生成它自己的线程。如果它确实生成了自己的线程,那么在尝试更新控件而不使用InvokeBeginInvoke时会遇到异常。

我会使用BackgroundWorker对象执行此操作,DoWork处理程序包含一个带有Thread.Sleep的循环。然后在DoWork循环中执行所有慢速ping操作,并使用一个GUI函数({1}}并更新图标。使用Invoke调用此GUI函数以在GUI线程上恢复GUI操作。

returnedPing

答案 1 :(得分:2)

这一切都取决于_pvpnetClient的发送方法运行的时间。

您正在运行System.Windows.Timer(我知道因为Tick事件),因此将在主线程上调用此方法,并且它将阻止所有GUI更新,直到完成为止。如果你想在另一个线程上完成工作,可以使用System.Timers.Timer对象,但是你必须调用主线程来更新GUI元素。