none
[UWP] OnSuspending throws unexpected error in Windows 10 version 1809 and later

    Question

  • Hi,
    Looking at the health report for my app in the Dev Center, I'm seeing increasing numbers of failures of the form 

    stowed_exception_system.exception_8000ffff_myappname.exe!myappname::app::_onsuspending_d__6.movenext

    However, this failure has only started to appear with Windows version 1809 (and the insider versions), where it accounts for over half the total failures. If I filter to Windows version 1803, then the percentage of crash-free devices is at 99.8%, but for build 1809 it is down at 80%, largely due to this specific failure.

    Therefore, the way the OnSuspending event is handled must have changed in Windows version 1809. I feel that maybe this is a bug whereby the deadline is not being properly reported in the OnSuspending arguments or the suspending handler is simply being cut off before the deadline. I can't see any reason for this error from my code as all I do in the suspending handler is get a deferral, invoke some cleanup code without awaiting, then check to see if more than 400ms are available until the deadline and if so do an await Task.delay(200) before calling deferral.Complete(). (To give the cleanup code a chance to finish if possible).

    Please can someone tell me if the new behaviour I'm observing is intentional (and if so please document it), or is it a bug?

    (I don't yet have the 1809 update myself so I can't test it, plus I find it hard to test the Suspending event effectively).

    Thanks.


    • Edited by Ben48 Monday, November 12, 2018 8:03 PM
    Monday, November 12, 2018 8:02 PM

All replies

  • Hi,

    Well, I could not tell something about this as I haven't test about this. Could you please share me a code snippet about what you are doing in the OnSuspending events? I need a demo to reproduce this issue on Build 1809 so that I could take a look at it.

    Best regards,

    Ry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, November 13, 2018 3:00 AM
    Moderator
  • Hi Roy,

    Thanks for the reply. The code is basically like this

    private async void OnSuspending(object sender, SuspendingEventArgs e) {
                var deferral = e.SuspendingOperation.GetDeferral();
                try {
                    foreach (var view in CoreApplication.Views) {
                        var task = view.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
                            System.Diagnostics.Debug.WriteLine("Run some cleanup code here");
                        });
                    }
                } catch (Exception) { }
                var timeRemaining = e.SuspendingOperation.Deadline.Subtract(DateTimeOffset.Now);
                if(timeRemaining.TotalMilliseconds > 400) {
                    await Task.Delay(200); //This should give a chance of closing some file handles
                }
                deferral.Complete();
            }

    Tuesday, November 13, 2018 8:21 AM
  • Probably you have to wait when cleanup tasks will complete their work

                var deferral = e.SuspendingOperation.GetDeferral();
    
                using (var runningTasks = new CountdownEvent(1))
                {
                    var currentView = CoreApplication.GetCurrentView();
                    
                    foreach (var view in CoreApplication.Views)
                    {
                        if (view != currentView)
                        {
                            runningTasks.AddCount();
    
                            await view.Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
                            {
                                try
                                {
                                    // Cleanup
                                }
                                finally
                                {
                                    runningTasks.Signal();
                                }
                            });
                        }
                    }
    
                    // Cleanup for main view
    
                    runningTasks.Signal();
    
                    runningTasks.Wait(e.SuspendingOperation.Deadline - DateTimeOffset.Now - TimeSpan.FromMilliseconds(5));
    
                    // Request extended execution session if needed
                }
    
                deferral.Complete();


    Wednesday, November 14, 2018 12:05 PM
  • Hi,

    Any updates?

    Does @Username already in use's reply make sense?

    Best regards,

    Roy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, December 6, 2018 10:03 AM
    Moderator
  • Thanks @Username already in use for trying to help, but that code as it stands is not a good idea. The Suspending event runs on the main UI thread so calling Wait() will block the main UI thread.

    I haven't had time to investigate yet. One thing I realised is that my try/catch handler is a bit useless since I'm not awaiting the tasks - I perhaps either need to use TryRunAsync or add a ContinueWith to the tasks to discard any exception. I will post an update when I've investigated further.

    Friday, December 7, 2018 9:01 PM