我写了一个应用程序,每隔10秒就通过FTP下载文件,我有以下计时器的代码。
timer3.Tick += new EventHandler(updateLogs);
timer3.Interval = (1000) * (10);
timer3.Enabled = true;
timer3.Start();
我的updateLogs功能:
timer3.Enabled = false;
server1_log = downloadLog("192.168.0.217", 1);
server2_log = downloadLog("192.168.0.216", 2);
server3_log = downloadLog("192.168.0.215", 3);
timer3.Enabled = true;
我意识到请求可能需要超过10秒,这就是为什么我在调用downloadLog()之前禁用定时器,然后启用它。
但是,大约一分钟后,应用程序冻结,CPU使用率跃升至45%以上。当我注释掉timer3的代码时,应用程序运行很长时间并且永远不会崩溃。
有什么想法吗?
答案 0 :(得分:5)
如果您使用System.Windows.Forms.Timer
,您应该期待这种行为。虽然这个类让你觉得它异步执行操作,但它实际上是使用UI线程来完成实际的工作。因此,如果计时器执行的逻辑卡住,您的用户界面也会停止。
为了缓解这种情况,你应该使用实际上可以在后台线程上工作的计时器,或者BackgroundWorker
。
.NET BCL中有三个Timer
类。
最适合您的需求是System.Timers.Timer(关于此问题的讨论会相当长。有关更多信息,请阅读MSDN Magazine article comparing these three)。
在异步进行工作并更新UI时,您还需要知道的是,您不能/不应该直接从工作线程访问UI。看看SO question regarding this topic。