Friday, 15 June 2012

A Lifetime of Events




Last week, I sat with a developer in an effort to solve an issue with broken Suspend-Resume handlers in Metro. The developer told me that he was getting inconsistent behaviour with his Suspend handlers and that he suspected a bug in the Metro framework.

When I got him to repro the bug, showing me how the error was caused and what the resulting output was, I found that he was not suspending and resuming but instead, suspending and on-launching.

He was exiting the application.

Metro triggers the suspend handler at that point. Suspend handlers run when you exit the application. Exit can be either suspending and leaving for a bit or quitting the application forever.

Now, one thing you should know about the Suspend handler is that it is paired with the Resume handler. If you can not see the Resume handler being called subsequently, after you add code to the Suspend handler then you are putting it in the wrong place.

The developer I was helping was putting his code in the wrong place. He was assuming that if he told Application.Current to persist something then it was so for as long as he waited to relaunch the application. He was wrong.

Web developers don't seem to hit this learning point but desktop developers do. It happens because they don't live inside life cycles. They have never been forced to understand that objects have lifetimes and you have to interact within the rules of that world.

When this developer called the Suspend handler and traced the persistance back to a file that stored the serialised version of his data, he assumed that it would be there when he started the app again.

That is an incorrect assumption.

Application lifetime lasts for the a the amount of time that the application is current. That means that when you launch it and when you exit it, the application is live. Outside of those boundaries, Metro does not guarantee anything. Files persisted to storage by the Application object are not always there and not always called the same thing. If it goes to disk, it could just as well go to memory and it is then just as fleeting.

There are matching pairs when it comes to exit-entrance handlers. With Suspend, you can count on Resume. With Exit, you can count on Launch.

Don't assume anything will be consistent, outside of the lifetime that your event belongs to.

If you want to ensure data or state persist then you must explicitly handle that persistence when it does not obey Application lifetime.

No comments: