DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations

Process Lifetime Management (PLM) and Managing State in Windows 8 Metro C# Applications

Jeremy Likness user avatar by
Jeremy Likness
·
Jun. 28, 12 · Interview
Like (0)
Save
Tweet
Share
8.21K Views

Join the DZone community and get the full member experience.

Join For Free

in the traditional windows environment, the user manages the lifetime of their applications. the user launches the application and it continues to run until the user decides to close it. the problem with this model is that applications continue to drain system resources, including memory and cpu, even when they are not in the foreground. this impacts the performance of the application the user is using as well as drains the battery faster when the device is not plugged in.

windows 8 metro applications only run when they are in the foreground. this allows the user to focus on the primary application they wish to interact with. applications in the background go into a suspended state. in the suspended state the threads for the application are literally frozen in place. the application will no longer take up system resources or impact battery life. most of the time, the application will remain in memory. this allows fast application switching, so when the user swipes back to a different application, it resumes immediately as if it were already running.

there is a case where the background application may be terminated by the system. this is based on system resources. for example, if the foreground application requires a large chunk of memory that will potentially result in a low memory state, the system may terminate one or more applications that are in the suspended state. it will target background applications based on their memory consumption and terminate the ones taking up the most resources first.

this is very easy to emulate. from visual studio 2012, create a new windows 8 metro project for c# using the grid template:

now launch the application in debug mode. it is easier to do this if you have dual monitors so that you can debug from one monitor and work with the metro application on the second; other options include launching into the simulator and remote debugging to another device. once the application is running, navigate to a few different pages. in visual studio 2012, choose the "suspend and shutdown" option.

you've just simulated the termination event. for many users, this will happen without them knowing when an application is in the background. when the user returns to the application, however, they will expect to continue where they left the application. you can simulate this by debugging and launching the application again. you'll find that you end up on the same page you left, and even the navigation history (i.e. the "back" button) is retained. how is this possible?

here is a rough visualization of process lifetime management in windows 8 metro applications:

to understand how you are able to preserve state in your application, it's also important to understand navigation. unless you are using a custom form of navigation, you are using the built-in frame class to manage your navigation. this class provides navigation services, as well as a place to host the target pages as they are loaded. in general, a navigation sequence looks something like this:

the navigation events are important because they provide a way to hook into the pipeline and are the logical way to preserve state. in the visual studio 2012 templates provided for metro applications, a bit of magic is created in the form of two important classes. first, if you inspect the pages of your application you will find they derive from the class layoutawarepage. this page handles a lot of housekeeping work for you. it will respond to orientation changes by updating the visual state of the page, and it handles navigation in conjunction with the second important class, suspensionmanager.

if you open the layoutawarepage source code, you will find a region for process lifetime management. in that region, you will find the navigation events are overridden. within these methods is code that manages the state of the application for you. it does this by creating a dictionary for each page that saves, among other things, the navigation parameters that were passed to the page. if you want to use this built-in system, the only rule is that whatever you pass as a navigation parameter can be serialized. this allows the suspensionmanager class to use the datacontractserializer to save the state for your application. to see how this works, launch the application again and navigate to a few pages, then terminate it.

double-click the package.appxmanifest file in the solution explorer and navigate to the packaging tab. read the package name:

now drop to a command line and type:

cd %userprofile%\appdata\local\packages

this will take you to the local folder where information is stored for your windows 8 metro applications. navigate to the directory that corresponds to the package name you found above. within that folder, you will find another folder called localstate. that folder contains a file named _sessionstate.xml. open that file and you'll find the serialized state for your application.

the way this mechanism works is straightforward. before the release preview, navigation was handled in a way very similar to the windows phone: navigation events received parameters and the application responded to those parameters. with the introduction of the built-in state management, the layoutawarepage intercepts navigation. instead of using navigation, you now use the loadstate and savestate methods instead.

these are wired for you in the templates. the layoutawarepage handles setting up a dictionary and saving any parameters passed to the page. when a page is navigated to, the loadstate method is called. here is an example that is generated by the default template:

protected override void loadstate(object navigationparameter, 
    dictionary<string, object> pagestate)
{
    var group = sampledatasource.getgroup((string)navigationparameter);
    this.defaultviewmodel["group"] = group;
    this.defaultviewmodel["items"] = group.items;
}

notice that the navigation parameter is automatically restored and passed in. if your application solely relies on navigation parameters, then everything is automatic. your application will function and users can navigate deep within the application, swap out, and return without losing navigation history. but what if you want to preserve your own values outside of the navigation parameters? that is easy enough.

in the groupeditemspage.xaml.cs file, change the pagetitle to hold a date instead. here is the code in the constructor:

public groupeditemspage()
{
    this.initializecomponent();
    pagetitle.text = datetime.now.tostring();
}

now there are just two steps needed to preserve the date. first, loadstate should check for a saved value and restore it if present. the first time the application is launched, the dictionary is empty, so make sure the dictionary exists before checking for the value:

if (pagestate != null && pagestate.containskey("date"))
{
    pagetitle.text = (string)pagestate["date"];
}

of course, you will also need to save the value. to save it, simply override the savestate method. you are conveniently passed the dictionary that is saved with the state for the page, so any information you wish to persist, you can simply add to that dictionary:

protected override void savestate(dictionary<string, object> pagestate)
{
    pagestate["date"] = pagetitle.text;
    base.savestate(pagestate);
}

and that's all there is to it! now you can launch the application, navigate to several different pages, suspend and terminate it, then load it again. you will find the date shown on the main page does not change because it is preserved using the built-in state management features. of course, if you have more complex types that don't serialize directly, you may need another strategy. i cover various methods for saving and restoring data, as well as serializing more complex types, in my book designing windows 8 metro applications with c# and xaml . happy windows 8 coding!

jeremy likness

(c) 2011-2012 jeremy likness.
application

Published at DZone with permission of Jeremy Likness, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Accelerating Enterprise Software Delivery Through Automated Release Processes in Scaled Agile Framework (SAFe)
  • Authenticate With OpenID Connect and Apache APISIX
  • Test Execution Tutorial: A Comprehensive Guide With Examples and Best Practices
  • Strategies for Kubernetes Cluster Administrators: Understanding Pod Scheduling

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: