10

我对该Application.Idle事件的了解是应用程序正在完成其处理并即将进入空闲状态。

我在某处读到

如果您有必须在线程空闲之前执行的任务,请将它们附加到此事件

那么这是否意味着任务将在线程空闲之前执行,还是在线程空闲之后执行?

我的项目中有一些代码,如下所示。是否在空闲时间执行数据库更新?

private void Application_Idle(object sender, EventArgs e)
{
    // Update the explorer's menuitems
    team.UpdateMenu();

    // Update display toolbars.
    team.UpdateToolBar();

    // Update SaveAll
    SaveAll.Enabled = teaj.IsModified;

    Up.Enabled = team.CanNavigateUp;
    ...
4

1 回答 1

29

首先,了解 Application.Idle不是关于“线程空闲”,而是关于应用程序 UI 线程上的消息处理。(线程空闲与消息循环空闲不同)

您的 WinForms 应用程序由从队列中拉出消息的消息循环驱动。当该队列被清空时,消息循环进入安静状态,高效休眠,直到下一条消息出现在消息队列中。这有助于节省 CPU 处理资源(循环中浪费的循环会占用机器上运行的其他进程的 CPU 时间,因此一切都感觉更慢),还有助于降低功耗/延长笔记本电脑的电池寿命。

您的应用程序的消息循环通常会相当频繁地耗尽消息队列积压 - 即使在您输入编辑框时击键之间也是如此。

Application.Idle 事件已成为一个方便的地方,可以与应用程序的主要操作异步处理应用程序的家务琐事,而无需涉及多个线程。

例如,当应用程序空闲时,通常启用或禁用菜单和按钮以匹配其相应的命令状态。由于可见外观只需要在用户时间内更新(与几毫秒后改变视觉状态相比,用户无法准确辨别在内部状态变化时视觉状态变化与视觉状态变化之间的区别),应用程序空闲事件是一个简单而有效的机会来处理这些家务。

您可以将代码放入 Winforms 应用程序的 Application.Idle 以检查数据库或网络资源。但是,您必须小心不要做任何需要“很长时间”的事情,因为如果您阻止 Application.Idle,您的整个应用程序 UI 将冻结。使用异步调用而不是阻塞调用。

另外,请记住,Application.Idle 事件触发的速率是高度可变的——它可能每秒触发多次,也可能在几秒钟内不触发,具体取决于用户和您的应用程序正在执行的操作。如果您想定期检查数据更新,您应该使用计时器事件而不是 Application.Idle。如果您在每次 Application.Idle 触发时启动异步网络请求,您可能会以每秒大量(冗余)请求淹没您的服务器。

于 2011-03-24T06:08:11.390 回答