2010-03-11 39 views
0

在Windows窗体的UI线程中是否存在(或者,你有自己的)首选方法在片段中执行后台处理?像MFC中的OnIdle()?在UI线程上的后台处理? (Winforms)

在本机Windows编程中,您可以滚动您自己的消息循环来执行此操作,但Application.Run()不允许我们访问消息循环。

Application.Idle事件让我们无法重复触发它。

我想你可以用P/Invoke(因为没有托管版本)调用本机PostMessage()来发布自己的私有“WM_IDLE”消息,并覆盖WndProc()来捕获它。我不知道这将如何与Application.Run()相处。

到目前为止,我已经为此使用了一个短暂定时器,但恐怕我可能会失去睡眠周期,尤其是因为实际的定时器分辨率比标称的1毫秒最少更粗。

回答

1

我见过的最好的选择是使用Managed DirectX Render Loop designed by Tom Miller的修改版本。通过在渲染循环中添加对Thread.Sleep()的调用,可以显着降低CPU使用率。

这确实需要一个P/Invoke调用来跟踪应用程序仍处于空闲状态,但只要空闲,您就可以制作一个“定时器”,在空闲阶段持续触发,并用它来处理。

这就是说,在现代系统中,你几乎总是有额外的核心。我会建议只在真正的后台线程上进行处理。

+0

1. AFAIK我的很多用户没有这个定义的“现代系统”。 2. UI正在快速使用由后台进程生成的新数据,因此所有常见的多线程问题。 3. 99%的工作是在后台进程中,因此用于UI和背景的独立内核不会购买更多的总吞吐量。 – 2010-03-11 01:23:38

+0

@Conrad:为什么我实际上给了你一个完全停留在UI线程上的选项......但是,即使是最近3-5年来的“低端”系统,通常也有2个内核。将所有处理置于后台线程中,即使在单核低端系统中,您也可以保持UI活跃,并且可能比在空闲时间尝试执行预定处理更容易。这就是说,上面的方法工作得很好... – 2010-03-11 16:24:39

+0

@康拉德:我只是意识到 - 我有错误的链接!我放在上面的那个应该更有意义......它将Application.Idle与AppStileIdle结合在一个循环中 - 允许你做你想做的事。 (对不起 - 我先前贴错了)。 – 2010-03-11 16:27:12

0

我想到了我自己可能的答案,灵感来自于里德关于多线程的讨论。我可能有一种方法来重新触发Application.Idle:

创建一个隐藏窗体,我们称之为formRetrigger。

在Application.Idle中,在线程池线程上启动我的Retrigger()方法。 ()调用formRetrigger.InvokeOnClick()(或任何其他“Control.Invoke”方法)。我希望这会通过应用程序的队列启动另一条消息,导致Idle再次触发。

相关问题