2009-02-25 4 views
1

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

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

Действительно ли это (все еще) для всех устройств? Есть ли способ, которым мы можем это сделать?

ответ

2

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

Общая идея приостановления должна быть прозрачной для приложения, и, прежде всего, это не очень хорошая идея.

+0

FYI цитата пришла отсюда: http://www.eggheadcafe.com/conversation.aspx?messageid=29469311&threadid=29469302 –

0

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

3

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

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

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

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

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

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

+0

Hooking во власть очередь уведомлений администратора более надежна, чем CeRunAppAtEvent. Вы можете получить уведомление об отключении питания, это просто, что устройство будет часто приостанавливаться до того, как ваш код сможет обработать событие. – ctacke

+0

Я этого не знал. Спасибо за информацию. –

0

В соответствии с 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.

Использование :: API запросов RequestPowerNotifications() и фильтрация для PBT_TRANSITION позволяет обрабатывать переходы как с POWER_STATE_SUSPEND, так и с POWER_STATE_UNATTENDED.

Проблема с обработкой POWER_STATE_SUSPEND заключается в том, что он обычно обрабатывается вашим кодом после того, как устройство было возобновлено. Я нашел в Интернете предложение использовать приоритет в реальном времени для потока, который вызывает :: ReadMsgQueue (..., INFINITE, ...) и выполняет обработку.

Для этого нам необходимо использовать CE-specific :: CeSetThreadPriority(), поскольку он позволяет устанавливать приоритеты в реальном времени. Я бесстыдно использую приоритет 0.

Как правило, таким образом я смог надежно обрабатывать POWER_STATE_UNATTENDED и не так надежно POWER_STATE_SUSPEND, потому что у меня была довольно трудоемкая работа (~ 2 секунды).

Для моей задачи обработки POWER_STATE_UNATTENDED это то, что мне действительно нужно обрабатывать.