1

我们在 Windows Mobile 上看到我们的应用程序偶尔会丢失一些数据,并且我们怀疑在设备挂起时某些缓冲数据没有被刷新到磁盘。我们想在设备即将挂起时手动将数据刷新到磁盘。在 Windows 上,我们通过捕获WM_POWERBROADCAST消息来做到这一点,但此消息在 Windows Mobile 上不可用。我在留言板上找到了一个两年前的报价,上面写着:

您需要意识到您*不*保证会在您再次醒来之前*收到暂停通知。也就是说,在设备重新唤醒之前,您可能不会收到通知。一般来说,你不应该因为这个限制而试图对暂停做出反应(无论如何,你可以做什么来响应事件的限制)。

对于所有设备,这(仍然)是正确的吗?我们有办法做到这一点吗?

4

5 回答 5

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);

如果您的应用程序作为后台应用程序运行,那么您需要将代码放在无人看管的电源模式块周围,同时执行上述代码。有关无人值守电源模式的更多详细信息,请参阅我的答案

于 2009-02-25T18:28:46.433 回答
2

引用(听起来非常非常熟悉)仍然是正确的。唯一保证能够在挂起之前完成其工作的组件是驱动程序,它们也有很多限制。

挂起背后的一般想法是对应用程序透明,而在此之前通常不是一个好主意。

于 2009-02-25T18:23:37.460 回答
0

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

于 2009-02-25T17:41:36.780 回答
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 的问题在于它通常在设备恢复后由您的代码处理。我在网上找到了一个建议,即为调用 ::ReadMsgQueue(..., INFINITE,...) 并进行处理的线程使用实时优先级。

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

一般来说,这种方式我能够可靠地处理 POWER_STATE_UNATTENDED 而不是那么可靠 POWER_STATE_SUSPEND 因为我的操作相当耗时(约 2 秒)。

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

于 2009-03-06T14:29:37.790 回答
0

也许这个 SO 问题的答案会有所帮助:如何在被挂起的情况下在 Windows Mobile 上运行代码?

于 2009-05-27T19:54:32.747 回答