Tombstoning, Dehydration, and Windows Phone – oh my!

On Saturday, Windows Phone Hacker editor Jaxbot wrote about a registry value he stumbled upon, that “disables the dehydration function of the task host”. All he knew at the time was a DWORD value controlled this behavior – HKLM\Software\Microsoft\TaskHost\DehydrateOnPause – and that applications appeared to resume faster. My notes on this follow but be warned. With all my notes, inaccuracy is very possible.

To ease into this, let’s walk through a typical Silverlight application scenario. Your application is deployed and is executing. You accidently brush the Windows button and your application is tombstoned. Tombstoning is the process of your application being killed off when you navigate away. To facilitate the illusion of pause/resume, the operating system saves a bit of state and passes it back to the application when you return (e.g. you tap the back button). Let’s be very clear here – whenever you navigate away from your application, it is terminated. It is not left behind in normal cases.

After the Silverlight application is tombstoned, various operating system-level cogs and gears stop spinning. The container in which your Silverlight application was running – the task host – starts cleaning up resources, including the .NET Framework. After it’s done, the container is tossed away. This process is called dehydration.

That brings us to this DWORD value. The DehydrateOnPause value controls the operating system’s Dehydration Policy. It can be set to a value ranging from 0 to 3.

  1. Don’t dehydrate
  2. Forcefully dehydrate
  3. Gracefully dehydrate
  4. Automatically decide

By default, Windows Phone ships with the Dehydration Policy set to 3. This instructs the task host – again, your application’s container – to gracefully dehydrate when possible. I admittedly don’t fully understand how eligibility is determined, but it appears opt-in is the default. (Some tasks, like the CameraCaptureTask, appear to opt-out.)

For the hackers out there, it appears you can control this behavior. Simply call the aygshell!SHSetAutoDehydratingHostEligibility function with an eligibility set to false to opt-out of dehydration. But you better be damn sure you handle the change in behavior properly (keep reading).

HRESULT SHSetAutoDehydratingHostEligibility(BOOL fEligible);

With the policy value set to 2, the operating system always starts the dehydration process. Differentiating it from forceful dehydration (policy value 1), a Win32 WM_CLOSE window message is sent to the application. In theory, this message could be processed and either ignored or accepted. It’s unclear if this message is simply an advance warning, in which dehydration would still continue, or if dehydration would be aborted.

Set to 0, dehydration is completely disabled. Your application will not terminate unless explicitly stopped. That means, for example, the .NET Framework is never shut down, your class instances aren’t destroyed, native resources left locked, etc. While this sounds great, given .NET Framework spin up is mainly the cause of the infamous resume screen, applications rarely behave properly in this scenario. After all, we were told to save state and abandon ship!

An easy way to see this in action is to create a Silverlight application with a sample page. In the page’s constructor, write some code. Tap the Search button on your phone, then tap the Back button. With dehydration disabled, this class is created once and left behind for re-use when your application resumes. Your constructor will not get called again.

Aside from all the quirks that arise from leaving junk behind, you also increase the chance of hitting out-of-memory (OOM) conditions. And with task host containers cluttering up RAM, their threads eat CPU cycles attributing to unnecessary battery power loss. (Admittedly, I don’t know how much loss we’re talking about here.)

So no, I wouldn’t fiddle with the dehydration policy on your phone.