4

在我的 WP8 应用程序中,我使用所有传感器。加速度计、指南针(来自 Windows.Devices.Sensors 和 Microsoft.Devices.Sensors)和倾角计。一切正常,直到我按下Windows按钮,然后按下后退按钮。我得到一个带有“正在恢复...”消息的全黑屏,但没有任何反应。一旦我遇到异常(仅从 5 失败开始):

{System.Runtime.InteropServices.SEHException: External component has thrown an exception.
   at Microsoft.Devices.Sensors.SensorBase`1.PauseSensor()
   at Microsoft.Devices.Sensors.SensorBase`1.<>c__DisplayClass7.<.ctor>b__4(Object sender, NotificationCallbackEventArgs args)
   at Microsoft.Devices.Sensors.SensorCallback.MS.Internal.Interop.INotificationCallback.Pausing(XPauseType pauseType)
   at MS.Internal.Interop.NotificationService.NotificationPausing(XPauseType pauseType)
   at MS.Internal.FrameworkCallbacks.NotificationPausing(UInt32 pauseType)}

有人遇到过这个例外吗?

或者是否有在 wp8 应用程序生命周期中正确使用传感器的最佳实践?

谢谢

4

2 回答 2

3

这个问题比我想象的要复杂。我在这方面做了很多工作。我分享我的发现,因为我认为我的经验也可以帮助以后的其他人。

我通过服务类使用传感器:这些类更新我的虚拟机,在虚拟机中我使用我的 DispatcherHelper 在 UI 上更新这些。我知道如果我想更新传感器的 valuechanged 事件中的 UI 绑定属性,我需要在事件处理程序中使用 dispatcherhelper 调用此更新,但我不知道如果它们与 VM 而不是 Views 通信时它们的行为如何。当我启动应用程序时,如果传感器具有新值,我在更新 UI 时没有任何问题。在这种情况下,我唯一的问题是,如果我想停用(按下 Windows 按钮)并激活(按下后退按钮)我的应用程序,我也不例外,我没有丢失调试会话,但只有一个带有“正在恢复”的黑页...”文本和运行进度条,什么也没发生。

我错过的是跨线程/访问异常。如果我使用 UI 绑定数据执行此操作,则会引发异常,但在这种情况下不会。

另一件事:加速度计(我有一个只与加速度计一起工作的版本)与模拟器一起工作,但在设备上却不行。我认为模拟器试图通过返回值来模拟加速器,但不是以正确的方式(没有线程问题)。

解决方案

如果我在 UI 线程的事件处理程序中更新(使用我自己的 DispatcherHelper)一切正常。这是一个很好的教训,在与传感器和其他层/线程(VM,V)交互时要始终注意。

于 2013-02-15T06:28:44.100 回答
1

这听起来确实像一个生命周期问题。

您是否尝试过在 App.Deactivated 事件上从 Microsoft.Devices.Sensors 的传感器上调用 SensorBase.Stop() 并在 App.Activated 事件上恢复使用 SensorBase.Start()?根据您的应用程序中有多少页面需要传感器访问,您甚至可以覆盖 OnNavigatedTo/OnNavigatedFrom 方法并使用它们。

您不必这样做,但根据您的应用程序,这可能是一个好主意。(您的应用程序是否支持锁屏空闲执行?它有后台代理吗?它是否在后台运行时尝试获取传感器读数?)

于 2013-02-12T00:51:13.157 回答