views:

2152

answers:

5

We are seeing some occasional data loss with our application on Windows Mobile, and we suspect that some buffered data is not being flushed to disk when the device is suspending. We would like to manually flush data to the disk when the device is about to suspend. On Windows, we do this by catching the WM_POWERBROADCAST message, but this message is not available on Windows Mobile. I found a two-year-old quote on a message board that said:

You need to realize that you are *not* guaranteed that you will be notified of the suspend *before* you wake up again. That is, you might not receive the notification until after the device has been reawakened. Generally, you should not be trying to react to suspend because of this limitation (and the limitation on what you can do in response to the event, anyway).

Is this (still) true for all devices? Is there a way we can do this?

A: 

Have you tried using the events that are exposed in OpenNETCF? I'm mainly a WinCE bod but I find it incredible that anyone would a release a platform that didn't reliably inform you of changes to power state as this is one of the most important differences between Desktop and Mobile device.

Quibblesome
+2  A: 

The quote (which sounds really, really familiar) is still true. The only components that are guaranteed to be able to complete their work before suspend are drivers, and they have a significant set of limitations as well.

The general idea behind a suspend is to be transparent to the application, and getting in front of that generally isn't a good idea.

ctacke
Graeme Perrow
+2  A: 

As far as I know you are correct that you can't detect when a device goes into suspend mode, only when it comes out using the CeRunAppAtEvent API.

A better approach to the problem is to try to prevent the device from suspending around critical parts of your code.

There are kind-of two ways to do this depending on how your application runs. If it runs as part of user interactions you need to call some API's to make sure that the device never goes into suspend mode.

You need to arrange the following code to run at least once every 10 seconds.

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

If you application is running as a background application then you need to put your code around a unattended power mode block while also doing the above code. See my answer for more details on unattended power mode.

Shane Powell
Hooking into the power management notification queue is more reliable than CeRunAppAtEvent. You can get the power off notification, it's just that the device will often suspend before your code can process the event.
ctacke
I didn't know that. Thanks for the info.
Shane Powell
A: 

According to http://social.msdn.microsoft.com/Forums/en-US/windowsmobiledev/thread/229dd6a2-f231-4aeb-ad90-c6995ba155cf/ besides POWER_STATE_SUSPEND on Windows Mobile there is also another power state POWER_STATE_UNATTENDED.

If WM device is being suspended you first get POWER_STATE_UNATTENDED and then POWER_STATE_SUSPEND.

Using ::RequestPowerNotifications() API and filtering for PBT_TRANSITION it is possible to handle transitions to both POWER_STATE_SUSPEND and POWER_STATE_UNATTENDED.

The problem with handling POWER_STATE_SUSPEND is that it is typically handled by your code after device has been resumed. I found on the Web a suggestion to use real-time priority for the thread that calls ::ReadMsgQueue(..., INFINITE,...) and does the handling.

For that we need to use CE-specific ::CeSetThreadPriority() because it allows for setting real-time priorities. I shamelessly use 0 priority.

Generally, this way I was able to reliably handle POWER_STATE_UNATTENDED and not so reliably POWER_STATE_SUSPEND because I had rather time consuming operation (~2 seconds).

For my task handling POWER_STATE_UNATTENDED is what I really need to handle.

A: 

Maybe the answer to this SO question is of help: How can I run code on Windows Mobile while being suspended?

vividos