我有一个应用程序会定期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;
}
答案 0 :(得分:2)
http://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.100).aspx
“基于服务器的Timer设计用于多线程环境中的工作线程。”
它不会自动生成它自己的线程。如果它确实生成了自己的线程,那么在尝试更新控件而不使用Invoke
或BeginInvoke
时会遇到异常。
我会使用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元素。