4

In my application on WP8 I work with all of the sensors. Accelerometer, Compass (from Windows.Devices.Sensors and from Microsoft.Devices.Sensors too) and Inclinometer. Everything works fine until I push the Windows button and after that the Back button. I get a full black screen with a "Resuming..." message and nothing happens. Once I got an exception (from 5 fauilure only once):

{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)}

Did someone meet with this exception?

Or is there a best practice working correctly with sensors during the wp8 application lifecycle?

Thanks

JustinAngel
  • 16,082
  • 3
  • 44
  • 73
Ferenc Kun
  • 428
  • 3
  • 13

2 Answers2

3

This problem was more complex than I thought. I’ve worked a lot with this. I share what I found because I think my experiences with it could help later someone else too.

I worked with the sensors through service classes: these classes update my VMs and in the VMs I use my DispatcherHelper to update these on the UI. I knew if I want to update UI bound properties in valuechanged events of the sensors I need to call this update in the eventhandler with a dispatcherhelper but what I did not know is how they behave if they are communicating with VMs instead of Views. When I started the app I had no problems with updating the UI if the sensors had new value. My only problem was in this case that if I wanted to deactivate (pressed windows button) and activate (pressed back button) my app, I had no exception, I did not lost my debug session but only got a black page with a „Resuming…” text and running progressbar and nothing happened.

What I missed was a crossthread/accessing exception. If I do it with a UI bound data it throws an exception but in this case it did not.

One other thing: the accelerometer (I had a version only working with the accelerometer) works with the emulator but on the device it does not. I think the emulator try to simulate the accelerator by giving back values, but not in a right way (without a threading issue).

Solution

If I update within an eventhandler on the UI thread (with my own DispatcherHelper) everything works fine. It is a good lesson learned, always pay attention when interacting with sensors and other layers/threads (VM,V).

Ferenc Kun
  • 428
  • 3
  • 13
  • Can you please explain how to pass Dispatcher to VM in your solution? Thank you. – Agile Hobo Sep 29 '13 at 15:42
  • Sorry for answering so late. I have an own little dispatcher helper class. A singleton class with a method to register the Dispatcher, Register(Dispatcher d) and an other method void Invoke(Action a) that checks the dispatcher and if isn't null calls the dispatcher.BeginInvoke(a) and I call the register method in my Bootstrapper class. UiDispatcher.Instance.Register(RootFrame.Dispatcher) or you call it from the MainView too or from elsewhere where you have the rootframe dispatcher. If it isn't clear I will post it in an other answer. – Ferenc Kun Oct 04 '13 at 20:10
1

It does sound like a lifecycle issue.

Have you tried invoking SensorBase.Stop() on the sensors from Microsoft.Devices.Sensors on the App.Deactivated event and resuming using SensorBase.Start() on the App.Activated event? Depending on how many pages in your app need sensor access you might even be able to override OnNavigatedTo/OnNavigatedFrom methods and use those.

You shouldn't have to do that, but depending on your app it might be a good idea. (does your app support lock screen idle execution? does it have background agents? does it try to take sensor readings while running in the background?)

JustinAngel
  • 16,082
  • 3
  • 44
  • 73
  • 1
    I call on my Compass (from Microsoft.Devices.Sensors) Stop(), but after some debugging I found it never finishes. I meen what I have after compass.Stop() never get called and if I let the debugger running after I navigated from my app it takes 1-2 minitues but I get an System.Runtime.InteropServices.SEHException (occurred in Unknown Module. but was not handled in user code). It looks like the Stop does not finish until the OS want to release app resources (--> terminated-phase) – Ferenc Kun Feb 12 '13 at 05:34
  • I called Stop() earlier too, but I had issues with lifecyclehandling in Caliburn.Micro and OnDeactivated in Bootstrapper was never called. But you have right it is always necessarily to call the Stop/Start on Sensores from SensorBase. – Ferenc Kun Feb 12 '13 at 05:39