In Xamarin.Forms Device.BeginInvokeOnMainThread() doesn’t show message box from notification callback *only* in Release config on physical device
Asked 07 September, 2021
Viewed 3K times
  • 61
Votes

I'm rewriting my existing (swift) iOS physical therapy app "On My Nerves" to Xamarin.Forms. It's a timer app to help people with nerve damage (like me!) do their desensitization exercises. You have these "fabrics" (e.g. a feather) where each fabric has an 'x' second countdown. When once fabric's timer reaches 0, a message box appears saying "time's up". The user hits OK and the next fabric starts its countdown. Rinse and repeat for all fabrics in the list. Here's a video showing the workflow. Trust me on the UX in the video.

Here's my sample app code demonstrating this behavior.

The DoSomethingForNow method (forgive my naming strategy) is the callback from the NotificationService (see line 65 - not enough SO rep points for direct link) that is created when the timer starts, in case the app gets the background.

The specific call that is not working on Release mode on Device is at line 115

Device.BeginInvokeOnMainThread(
                async () => await ShowAlertAndWaitForUser(currentFabricCount));

The async () => await ShowAlertAndWaitForUser(currentFabricCount)) works as expected in Debug and Release configuration on iOS Simulator, and in Debug configuration on the device.

However, the message box indicating time is up does not appear in Release config on the physical device. I cannot figure out why Device.BeginInvokeOnMainThread() doesn't work in Release config on device. What is going on?

Side note re using Device.StartTimer()

The reason why I switched from Device.StartTimer() to James's FrenchPressTimer solution (see jamesmontemagno/FrenchPressTimer) early on is because I need a way to cancel / stop / whatever a Device.StartTimer() in case the user needs to pause or stop the countdown on the app.

The Device.StartTimer() code works great for me on all configurations on both simulator and device and thankfully someone showed me how to cancel a Device.StartTimer (thanks!). If you want to see this working solution, check out saraford/Device-StartTimer-Working-Xamarin on GitHub.

My specific question is why doesn't Device.BeginInvokeOnMainThread() display a message box when invoked from a notification callback in Release config on a physical device.

I've also tried the different linker combinations. No effect.

4 Answer