2009-02-25 103 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是我真正需要處理的。