0
votes

We have a Xamarin UWP app that needs to be logged out whenever a user minimizes or clicks away from the window.

In my App.xaml.cs I have registered an event handler for the Suspending event. I then put our logout code in this event handler like so:

private void OnSuspending(object sender, SuspendingEventArgs e)
{
    var deferral = e.GetDeferral();
    AppBackgrounded();
    deferral.Complete();
}

This AppBackgrounded() method looks like this:

void AppBackgrounded()
{
    if (!_isInBackgroundMode)
    {
        _isInBackgroundMode = true;
        if (UserSetPin)
        {
            PinPage passcodePin = new PinPage();
            Navigation.PushModalAsync(New NavigationPage(passcodePin), false);
        }
        else
        {
            App.Logout(null, true, true);
        }
        // clears the pasteboard so data can't be copied from this app into other apps 
        Clipboard.Clear();
    }
}

We also have a AppLeavingBackground method that we use to restore the app when the user returns, but the app does not crash when returning. It only crashes when running the OnSuspended method.

This crash only occurs when

  1. The App is built for release and
  2. The device is in tablet mode

When in tablet mode, if you press the Task View button and navigate to another application the UWP app freezes trying to run through this code. If you try to return to the app, it will immediately exit.

I have tried to make the navigation to the other pages async and the app will then crash even when its not in tablet mode. I have also tried to put this logic in AppEnteredBackground and it still occurs.

This is hard to debug since it only occurs in release mode. Any ideas?

2
You probably need to start with logging around these areas to work out where is gets to before the freeze. It could also be worth adding in some exception handling and additional logging to check whether any exceptions are being thrown but not killing your app.Bijington
Release mode uses .net native, you can also activate .net native in debug configuration and debug the app.magicandre1981
An async method "PushModalAsync" is being called without an await. Deferral.Complete might be called before Navigation.PushModalAsync finishes executing. It may not be the source of the crash problem, but it is a problem is your code. Add await before PushModalAsync(...) and AppBackgrounded() calls; then make AppBackgrounded and OnSuspended async methods.Mehrzad Chehraz

2 Answers

1
votes

In my case it was the Clipboard.Clear() function that was crashing the application. For those encountering similar issues, checkout the other answers as they all provide great points.

As a side note, I also found that using async code in these events was crashing my application. I'm not sure why since I was using the deferral, but since it's working i'm not going to pursue it further.

0
votes

I cannot say that I have read exactly the documentation that says that navigating the pages in suspending will result in a crash, but it is clear that this is the wrong place to do it.

The suspending is not used to prepare your app to be opened again, the whole reason for this lifecycle event is that you need to prepare your app for not being open again, which means saving some data that may eventually get lost. Preparing your app to be opened again is done in resuming.