0

我编写了一个应用程序,它每 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 的代码时,应用程序可以正常运行很长时间,并且从不崩溃。

有任何想法吗?

4

1 回答 1

5

如果您正在使用System.Windows.Forms.Timer,您应该期待这种行为。尽管这个类给你一种它异步执行操作的错觉,但它实际上是在使用 UI 线程来做实际的工作。因此,如果你的计时器执行的逻辑卡住了,你的 UI 也会卡住。


为了缓解这种情况,您应该使用实际上在后台线程上工作的计时器,或者使用BackgroundWorker.

.NET BCL中有三个Timer类。

  1. System.Windows.Forms.Timer
  2. System.Threading.Timer
  3. System.Timers.Timer

最适合您的需求是System.Timers.Timer(关于此的讨论会相当长。有关更多信息,最好阅读MSDN 杂志比较这三个的文章)。

在异步执行工作和更新 UI 时,您还需要知道的是,您不能/不应该直接从工作线程访问 UI。看看关于这个主题的 SO question

于 2012-08-15T15:12:58.750 回答