locked
App terminated in middle of OnSuspending method despite of SuspendingDeferral RRS feed

  • Question

  • I know that one has to use SuspendingDeferral to prevent that an async OnSuspending method is interrupted.

    However, I found a strange and frightening behaviour:

    If the user closes the app via Alt+F4 or the Close Gesture, and waits exactly till the app is being suspended (let's assume the OnSuspending method takes 1 second) and starts the app again while the "old" one is still in the middle of the OnSuspending method, then the "old" instance is terminated abruptly. (It is difficult to hit the OnSuspending method in the middle, but it is not impossible)

    This is a huge problem: (Problem 1) This can cause corrupted data for the app and it is possible that the app will never ever be working properly.

    There is another problem if the user restarts the app after closing it and before it is suspended: (Problem 2): The OnSuspending method of the "old" instance is never called. This is not as dramatic as Problem 1, but nevertheless, information is lost (since never saved). This problem is not as dramatic as Problem 1 because there will not be corrupted data (just too old data).

    I could accept Problem 2, but I fear Problem 1: Corrupted data is the worst what can happen to a program.

    I for myself don't see a solution. It is not possible to save all data after each and every user step. But the user expects an app which was terminated normally (i.e. after the app was in background for some time and was suspended and then terminated) to have all data.

    But if I cannot save all data after each and every user step, the Suspending event is the only chance for me to save the data. Or am I missing something?

    Thursday, May 2, 2013 7:57 PM

Answers

  • This is expected behavior. Suspend doesn't occur immediately, and users who restart the app don't want to wait for it to complete.

    Save out state information needed to get back to the same page and location in the app when suspending.

    Save out data more often. This doesn't have to be at every change, but consider other checkpoints such as window deactivation, visibility changed, etc.

    --Rob

    Thursday, May 2, 2013 8:24 PM
    Moderator

All replies

  • This is expected behavior. Suspend doesn't occur immediately, and users who restart the app don't want to wait for it to complete.

    Save out state information needed to get back to the same page and location in the app when suspending.

    Save out data more often. This doesn't have to be at every change, but consider other checkpoints such as window deactivation, visibility changed, etc.

    --Rob

    Thursday, May 2, 2013 8:24 PM
    Moderator
  • Rob, thank you for your reply!

    So, you are saying that it is a bad idea to save data ("what is the user input?") in contrast to just app state ("on which page is the user?") based on the Suspending event? So, you are saying: "Never write data in the Suspending event"?

    But this means that all documentation is wrong, e.g.

    http://msdn.microsoft.com/en-US/library/windows/apps/xaml/hh465115

    "When your app handles the Suspending event, it has the opportunity to save its important application data"

    Or let's take all books on Windows 8, e.g. Charles Petzold "Programming Windows, Sixth Edition", page 246:

    "An application uses this event [Suspending] to save unsaved data in local application storage."

    So, all of this is totally wrong.

    You are suggesting to use the VisibilityChanged event instead. But what if saving the data takes 1 second and the user restarts the app within this second? It is the same problem (Ok, it is a little bit harder to get the app in a corrupted state, but it is still possible).

    Another option would be to save the data in a temporary file first. And then move this file to the right name/location. Is it guaranteed by the operating system that this moving is an atomic operation? (Either it is performed 100% or it is not performed at all?)

    I cannot understand that Microsoft chose the way to kill an app immediately. I would have been possible to suddenly raise the Suspending event, wait some seconds for it to complete while displaying the splash screen and only then start a new process. I think waiting 4 seconds in a very rare case is better for the user than having a corrupted app in a very rare case.



    • Edited by eikuh Friday, May 3, 2013 8:09 AM
    Friday, May 3, 2013 8:07 AM
  • If I save the data in a temporary file first, and then move this file to the right name/location. Is it guaranteed by the operating system that this moving is an atomic operation? (Either it is performed 100% or it is not performed at all?)

    Or can Windows kill the process in the middle again?

    Tuesday, May 7, 2013 7:37 AM
  • hey there,

    I don't think Rob is saying "don't use suspending event", he is just saying you can use other events to save data as well as the suspending event. Plus suspending event is suggested to be used to save the transient data in the application (i.e. viewmodel, current page, etc.) This data should not be crucial for the execution of the application, but just provides ease of use. if the data on the application is crucial for the execution, you might want to save it, as you said, after each step.

    And the reason for suspending event to fire in couple of seconds to enable application fast switch.. As in you don't want the application to go on suspension immediately when you just want to check something in another app. In games and other applications, developers choose to use VisibilityChanged to stop timers, or have a, so-to-say, "soft suspend".

    Also the temporary file idea is not a bad one at all, you can even use a background task to consolidate this data into the main storage in timely manner or with another system trigger. For the background task you wouldn't need the main application to be running. But, you can as well consolidate the data when the user actually needs it when the application is running again.

    hope it helps..


    Can Bilgin
    Blog Samples CompuSight

    Tuesday, May 7, 2013 8:12 AM
  • > I don't think Rob is saying "don't use suspending event"

    As I understand, he is saying "don't use suspending event if the data is important". In my opinion, this should be documented in the docs. I think, 98% of the developers think that the suspending event is the one to choose when saving important data.

    > And the reason for suspending event to fire in couple
    > of seconds to enable application fast switch..

    I understand why the suspending event is fired only with a delay about 10 seconds under normal circumstances. However, if Windows wants to kill the application because another process should be started, then Windows could fire the suspending event immediately.

    > Also the temporary file idea is not a bad one at all

    The remaining question is: Is it guaranteed by the operating system that moving/renaming a file is an atomic operation? (which is either performed 100% or not at all)

    > you can even use a background task [for saving]

    Yes, you are right. But using a background task just for saving is too complicated and cumbersome for me.



    • Edited by eikuh Wednesday, May 15, 2013 8:05 AM
    Wednesday, May 15, 2013 8:04 AM
  • hey there,

    Couple of things about the items you commented on... Hope some of them would help..

    1) I know this presentation, by Ben Srour - MS Senior Program Manager Lead,  is a bit old but there are some interesting and related statements... (Fundamentals of Metro Style Apps: How and When your app will run)

    Here is a table from the presentation:

    Scenario                                                       You should…

    User is using your App                                   Save user data incrementally
    App switched away from (Suspending)            Save where the user is – what screen they are on, for example
    Not running App launched by user (Activated)  Bring the user back and restore their session as if they never left
    Suspended App launched by user (Resuming)   Do nothing

    2) For the termination to happen your application should already be in the suspended state. If windows is killing your app, that means that your application was the biggest memory offender in suspend state. This would be a termination and you do not receive any notifications in this case. Not sure if you would receive the suspend event earlier if you have just switched your app to the background and system needs resources immediately.

    3) This depends really... If the file IO operation is taking more than the allowed time (was it 15 secs. ?), this would cause an app crash, and the suspension is terminated immediately. And your application would not resume or activate next time, it would launch with previous execution state NotRunning. So I guess the answer is no, you cannot count on it.

    4) I can imagine... This might prove to be cumbersome, and cause unnecessary implementation for a simple application.

     


    Can Bilgin
    Blog Samples CompuSight

    • Edited by Can Bilgin Wednesday, May 15, 2013 8:37 AM
    Wednesday, May 15, 2013 8:36 AM
  • Thank Can, for your post!

    1) Yeah, there are presentations/documentations that got it correct. What I was trying to say is that it is wrong in the official docs and it is wrong in all books on Windows 8 that I know. So Microsoft should change some sentences to clarify that the Suspending event is not suited to save important data. And Microsoft should write to many book authors so they can change this in future publications.

    2) ??? We were talking about Windows killing the app when it is in foreground, the user closes it via Alt+F4 or Close gesture and then restarts the app again within 10 seconds.

    Friday, May 17, 2013 1:24 PM