Forcing Metro Apps to terminate

As explained in Reclaiming memory from Metro style apps, Windows 8 optimizes the way RAM is dedicated to running processes. Metro Apps are even more impacted than just reclaiming memory from their working set because the system can decide to simply terminate the suspended ones when low memory conditions are detected. It is important to take care of this scenario when you write your code so the user, who is unaware of the App termination expects to get back where he was when he clicks on its tile: this is part of the PLM (= Process Lifecycle Management) and I’ll spend some time describing the basics before returning to the hidden termination case.

Download ByeBye tool.

PLM Basics

In previous versions of Windows, WinMain/Main was the only single entry point called by the system to start your application via the main thread process. In Wndows 8, a Metro App provides several entry points by implementing the IApplicationOverrides interface:

By default, your Application derived class code usually implements only the OnLaunched method that is called when the user clicks the App tile. The other methods are called when the App gets activated via different Contracts such as Search or Share target as explained in Activating Windows 8 contracts in your app.

Each method receives an instance of a type inherited from IActivatedEventArgs:
 that provides three properties:

The Kind property repeats the activation reason via the ActivationKind enumeration. The SplashScreen property references an object that lets you know where the splashscreen bitmap you defined in the App manifest is displayed on the screen and also when it is dismissed (see the Extended Splashscreen SDK Sample for implementation details about how to use it).

The third PreviousExecutionState property tells you what is the reason why your App ends its life at the end of its previous execution.

  • If the user closed the App by using ALT+F4 keyboard shortcut or via the swipe downward touch gesture, the Suspending event is first received so you can save anything you need before Windows closes the App. In that case, your activation override will receive the value ClosedByUser for the PreviousExecutionState property and you are supposed to display the main page of the App.
  • The Running value is received by the overrides related to Contracts (all except the OnLaunched override) when the App is already running.
  • Same for the Suspended value which is received when the App gets activated by a Contract while it is suspended.
  • If the App was never started since the user logged in or crash, the value will be NotRunning.
  • The Terminated value is set by Windows when the App was terminated due to system optimization such as in the case of low memory condition I mentioned earlier. The default Visual Studio template for Metro App generates code that handle this special case and let you know where to restore your state with the following comment
    //TODO: Load state from previously suspended application

Unlike the activation methods your application code implement from IApplicationOverrides, the Suspending and the Resuming events are defined in the IApplication interface that your Application type also implements:

You usually register listeners in the Application constructor. The Suspending event is triggered around 10 seconds after the App leaves the foreground when the user decides to use another App (either Metro or Desktop application). In some cases such as games, you don’t want you App to run in the background for 10 seconds without any user interaction. You can use a nice trick to be notified immediately by registering a listener to the VisibilityChanged event in the current navigated to window. Here is the schedule of these events traced by Debug.WriteLine calls intercepted by the DebugView tool from SysInternals as I’ve already explained :

What are you supposed to do in your Suspending event handler? Well… save the state corresponding to what the user is doing (remember that you are supposed to restore this state in the application overrides only when the previous state is Terminated). A good example is the Mail App that saves the text the user enters while writing an email. That way, if Windows decides to terminate the App, when it will be reactivated, the same state will be restored without the user even noticing anything. See Process Lifetime Management (PLM) and Managing State in Windows 8 Metro C# Applications by Jeremy Likness from Wintellect to get the details of current navigation save/restore feature provided by the Visual Studio C# templates.

If you take more than 5 seconds to save your App state, Windows will terminate it because it is assuming that your code has a bug and should not continue to run. This value of 5 seconds is given by the Deadline property of the SuspendingEventArgs provided to the Suspending event handler:

When the App gets suspended, Windows stops scheduling its threads until it gets resumed by the user. The Windows TaskManager allows you to detect such suspended Apps but you first have to check the View | Status values | Show suspended status menu item:

How to debug automatic termination and contract activation

Debugging your overrides and Suspending/Resuming handlers is not an obvious task. Why? Because a Metro App behaves in a different way while running under the control of a debugger such as Visual Studio. In that case, the threads are never suspended because otherwise the Debugger would also be suspended. So, a debugged Metro App will never receive the Suspending event even though it is in the background while the user uses another application. As explained in How to trigger suspend, resume, and background events in Metro style apps, Visual Studio provides special toolbar commands to emulate these events.

While I’m talking about Visual Studio, let’s quickly see how to debug your activation overrides. If you debug your Metro App, Visual Studio will start the App. However, this is not what you want to debug your activation overrides such as when the user submit a search string while your App is not running already (yes… your App has to support this kind of activation :^). In that case, you need to change the Debug project configuration and check the “Do not launch, but debug my code when it starts“ setting:

Now, when you debug your App, nothing visible happens. However, when you activate the App via any supported contract, the breakpoints you’ve set in the corresponding override are triggered and you jump into Visual Studio debugging experience.

How to test automatic termination

If you need to test that your application behaves appropriately outside of a Visual Studio debugging session, things are getting a little more complicated. Before the Release Preview, you simply needed to wait for the App to get suspended and right click it in TaskManager to choose the End Task context menu item. The next time the App was started, the handlers would have received the right Terminated state. Unfortunately, this is no more the case.

I’ve noticed that if you start (not debug) the application from Visual Studio while it is running, it gets terminated the right way and the Terminated value is received as expected. However, what to do if there is no Visual Studio installed? This is the role of my new ByeBye tool:

When you click the “Add Memory Pressure” button, it sets its own maximum working set size to the size of the RAM in the machine and starts to allocate chunks of 256MB of commited memory until it detects that Windows is running under low memory condition. At that moment, it stops allocating chunks and the chip logo starts to blink:

Click the now renamed “Remove Memory Pressure” button to free the allocated chunks.

Here is the list of the APIs used by the tool:

As you can see, the tool uses brute force to emulate low memory condition that forces Windows to reclaim memory from Metro Apps, up to terminate most of them. However, it might happen that the pressure is not even enough and that you might have to repeat memory pressure in ByeBye in order to force Windows to terminate your App.

References

You have to watch the deep dive on Windows memory management by Mark Russinovich’s “Mysteries of Windows Memory Management Revealed”: part 1 & part 2.

Process Lifecycle Management in MSDN

I hope this helps

About these ads
This entry was posted in Metro and tagged , , , , , , . Bookmark the permalink.

14 Responses to Forcing Metro Apps to terminate

  1. Pingback: Windows 8 Developer Links – 2012-07-09Dan Rigby | Dan Rigby

  2. Pingback: Forzare il termine di un’app Metro « C# Mania

  3. “Forcing Metro Apps to terminate | Anything about WinRT” was indeed a
    perfect post. If it included even more photographs it might
    be even more effective. Thank u ,Shayna

  4. I question exactly why you labeled this specific posting,
    “Forcing Metro Apps to terminate | Anything
    about WinRT”. No matter what I really loved the blog!
    Thanks for your time-Lea

    • You’re right on one way: I could have named it “Windows 8 forces Metro Apps to terminate” or “how a Metro App should handle automatic termination”. Would have it been better? But on the other way, I’m presenting a tool that “forces Metro Apps to terminate” so… this is why I picked this title :^)

  5. I personally contemplate the reason you called this specific posting, “Forcing Metro Apps to terminate | Anything
    about WinRT”. In either case I really admired the post!
    I appreciate it-Frieda

  6. Hey there just wanted to give you a quick heads up
    and let you know a few of the pictures aren’t loading properly.

    I’m not sure why but I think its a linking issue.
    I’ve tried it in two different web browsers
    and both show the same outcome.

  7. Rob says:

    Thank you! I tried using ByeBye tool, but my tablet is an ARM tablet. Thankfully you described what calls you make so I can try and build an ARM version. Or you could build it, or post source :)

    • Unfortunately, it is not possible to compile and deploy a desktop app to a Windows ARM device…

      • Rob says:

        I tried and sadly figured that out. I making a ‘Windows Store’ app and I’m using non-permitted calls to accomplish the same thing. I’m not done yet, but since this is a test app I don’t have to pass the Windows Store test.

      • Maybe you will be able to call the Win32 API via P/Invoke but I’m not sure it will work at runtime… Good luck!

      • Rob says:

        I ended up making a c++ library so I could just prototype the missing functions and everything seems to be working just fine. All those nice kernel calls are there on the ARM tablet, just hidden from us. I don’t know how long they will be there, but for the time being, I’m happy to be able to test termination better.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s