我有一个应用程序会定期对服务器执行 ping 操作,以告知您连接的延迟时间。根据我的阅读,System.Timers.Timer
在与 UI 不同的线程上运行。
public MainForm()
{
InitializeComponent();
_timer = new Timer();
_timer.Tick += new EventHandler(timer_Tick);
_timer.Interval = 1000;
_timer.Start();
}
我有一个 NotifyIcon
和一个显示此 ping 结果的 ContextMenu
。但是我注意到每次计时器滴答时 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;
}
最佳答案
http://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.100).aspx
“基于服务器的 Timer 设计用于多线程环境中的工作线程。”
它不会自动生成它自己的线程。如果它确实生成了它自己的线程,那么当您尝试在不使用 Invoke
或 BeginInvoke
的情况下更新您的控件时,您会遇到异常。
我会使用 BackgroundWorker
对象来执行此操作,该对象的 DoWork
处理程序包含一个带有 Thread.Sleep
的循环。然后在 DoWork
循环中执行所有缓慢的 ping 工作,并有一个 GUI 函数接受 returnedPing
并进行图标更新。使用 Invoke 调用此 GUI 函数以将 GUI 操作返回到 GUI 线程。
class SlowOperation
{
BackgroundWorker m_worker;
void StartPolling()
{
m_worker = new BackgroundWorker();
m_worker.WorkerSupportsCancellation = true;
m_worker.WorkerReportsProgress = true;
m_worker.DoWork += m_worker_DoWork;
m_worker.ProgressChanged += m_worker_ProgressChanged;
}
void m_worker_DoWork(object sender, DoWorkEventArgs e)
{
while (!m_worker.CancellationPending)
{
int returnedPing = 0;
// Get my data
m_worker.ReportProgress(0, returnedPing);
Thread.Sleep(1000);
}
}
void m_worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
myForm.Invoke(myForm.UpdateMyPing((int)e.UserState));
}
}
关于c# - 应用程序滞后于每个计时器滴答,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15879013/