Как я могу обнаружить приостановку в Windows Mobile?

Мы наблюдаем случайную потерю данных с нашим приложением в Windows Mobile и подозреваем, что некоторые буферизованные данные не сбрасываются на диск, когда устройство приостанавливается. Мы хотели бы вручную сбросить данные на диск, когда устройство собирается приостановить работу. В Windows мы делаем это, перехватывая WM_POWERBROADCAST сообщение, но это сообщение недоступно в Windows Mobile. Я нашел на доске объявлений цитату двухлетней давности, в которой говорилось:

Вы должны понимать, что вам * не * гарантировано, что вы будете уведомлены о приостановке * до * того, как вы снова проснетесь. То есть вы можете не получить уведомление до тех пор, пока устройство не будет повторно пробуждено. Как правило, вы не должны пытаться реагировать на приостановку из-за этого ограничения (и, в любом случае, ограничения того, что вы можете делать в ответ на событие).

Это (по-прежнему) верно для всех устройств? Есть ли способ сделать это?

Ответов (5)

Решение

Цитата (которая звучит очень, очень знакомо) по-прежнему верна. Единственные компоненты, которые гарантированно завершат свою работу до приостановки, - это драйверы, и они также имеют значительный набор ограничений.

Общая идея приостановки заключается в том, чтобы быть прозрачным для приложения, и выходить из-под контроля, как правило, не очень хорошая идея.

Вы пробовали использовать события, представленные в OpenNETCF? В основном я использую WinCE, но мне кажется невероятным, что кто-то выпустит платформу, которая не будет надежно информировать вас об изменениях в состоянии питания, поскольку это одно из самых важных различий между настольным и мобильным устройством.

Насколько я знаю, вы правы в том, что вы не можете определить, когда устройство переходит в режим ожидания, только когда оно выходит с помощью API CeRunAppAtEvent .

Лучший подход к проблеме - попытаться предотвратить приостановку работы устройства рядом с критическими частями вашего кода.

Это можно сделать двумя способами, в зависимости от того, как работает ваше приложение. Если он работает как часть взаимодействия с пользователем, вам необходимо вызвать некоторые API, чтобы убедиться, что устройство никогда не переходит в режим ожидания.

Вам необходимо настроить запуск следующего кода не реже одного раза в 10 секунд.

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

Если ваше приложение работает как фоновое приложение, вам нужно поместить свой код в блок автоматического режима питания, одновременно выполняя приведенный выше код. Подробнее об автоматическом режиме питания см. В моем ответе .

Может быть, ответ на этот SO-вопрос поможет: как я могу запустить код на Windows Mobile во время приостановки?

Согласно http://social.msdn.microsoft.com/Forums/en-US/windowsmobiledev/thread/229dd6a2-f231-4aeb-ad90-c6995ba155cf/ помимо POWER_STATE_SUSPEND в Windows Mobile существует еще одно состояние питания 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 - это то, с чем мне действительно нужно справиться.