2009-02-25 51 views
1

我们在Windows Mobile上看到我们的应用程序偶尔会出现一些数据丢失,并且我们怀疑当设备挂起时,某些缓冲数据没有被刷新到磁盘。我们希望在设备即将挂起时手动将数据刷新到磁盘。在Windows上,我们通过捕获WM_POWERBROADCAST消息来完成此操作,但此消息在Windows Mobile上不可用。我在a message board上发现了一段两年的报价,内容如下:如何检测Windows Mobile上的挂起?

您需要认识到,您*无法得到保证,因此在您醒来之前您会被通知暂停*。也就是说,直到设备被重新唤醒之后,您才可能收到通知。一般来说,你不应该因为这个限制而试图对暂停做出反应(并且无论如何都会限制你对事件的反应)。

这是(仍然)适用于所有设备?有没有办法可以做到这一点?

回答

2

引用(这听起来确实很熟悉)仍然如此。保证在暂停前完成工作的唯一组件是驱动程序,并且它们也有一些重要的限制。

挂起背后的一般想法是对应用程序是透明的,并且通常不会是一个好主意。

+0

仅供参考报价从这里走过:http://www.eggheadcafe.com/conversation.aspx?messageid=29469311&threadid=29469302 – 2009-02-25 18:44:37

0

您是否尝试过使用OpenNETCF中公开的事件?我主要是一个WinCE bod,但我觉得难以置信的是,任何人都会发布一个不能可靠地告诉你电源状态变化的平台,因为这是桌面和移动设备之间最重要的区别之一。

3

据我所知,你是正确的,你无法检测到一个设备进入暂停模式时,只有当它出来使用CeRunAppAtEvent API。

解决此问题的更好方法是尝试防止设备挂起代码的关键部分。

根据应用程序的运行方式,有两种方法可以实现此目的。如果它作为用户交互的一部分运行,则需要调用一些API来确保设备永远不会进入挂起模式。

您需要安排以下代码,每10秒至少运行一次。

::SystemIdleTimerReset(); 
    ::SHIdleTimerReset(); 
    ::keybd_event(VK_LBUTTON, 0, KEYEVENTF_SILENT, 0); 
    ::keybd_event(VK_LBUTTON, 0, KEYEVENTF_KEYUP | KEYEVENTF_SILENT, 0); 

如果应用程序正在运行的后台应用程序,那么你需要把你的代码围绕一个无人值守的电源模式块,同时还做了上面的代码。有关无人值守电源模式的更多详细信息,请参阅我的answer

+0

挂钩插入电源管理通知队列比CeRunAppAtEvent更可靠。您可以获得关闭电源的通知,只是在您的代码处理事件之前,设备通常会暂停。 – ctacke 2009-02-25 18:53:26

0

根据http://social.msdn.microsoft.com/Forums/en-US/windowsmobiledev/thread/229dd6a2-f231-4aeb-ad90-c6995ba155cf/除了Windows Mobile上的POWER_STATE_SUSPEND,还有另一个POWER_STATE_UNATTENDED电源状态。

如果WM设备被暂停,您首先得到POWER_STATE_UNATTENDED,然后是POWER_STATE_SUSPEND。

使用:: RequestPowerNotifications()API和过滤PBT_TRANSITION,可以处理同时转换到POWER_STATE_SUSPEND和POWER_STATE_UNATTENDED。

处理POWER_STATE_SUSPEND时遇到的问题是,设备恢复后通常由代码处理。我在Web上发现了一个建议,对调用:: ReadMsgQueue(...,INFINITE,...)的线程使用实时优先级并进行处理。

为此,我们需要使用CE特定:: CeSetThreadPriority(),因为它允许设置实时优先级。我无耻地使用0优先级。

通常,这样我就能够可靠地处理POWER_STATE_UNATTENDED,而不是如此可靠地处理POWER_STATE_SUSPEND,因为我的操作相当耗时(〜2秒)。

对于我的任务处理POWER_STATE_UNATTENDED是我真正需要处理的。