Wednesday, June 27, 2012

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

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

Thursday, June 21, 2012

Video: The Top 10, er, 11 Features Developers will Love about Windows 8

I downloaded the Developer Preview for Windows 8 within minutes of it being announced during the major //BUILD conference in September 2011. Since then, I've been working with Windows 8 on both a laptop and a slate and have come to love several features. I wrote about the top 10 features I think developers will love in this article and have developed this into a talk.

I had a great time presenting this talk on June 20th to an international audience through the LinkedIn .NET User Group (LIDNUG). In this presentation I elaborated on those features as well as an 11th (you may recall my earlier series on the Portable Class Library). This presentation was done entirely on a Samsung Series 7 slate, including the live coding examples. The session was recorded and the full 90 minutes are posted here for you.

Jeremy Likness

Monday, June 18, 2012

Introducing the Microsoft Surface Tablet with Windows 8

Today Steve Ballmer stepped up on stage and stated that while we’ve seen great change with things like cloud computing, Windows is the “heart and soul” of Microsoft. There are over 1 billion PCs including embedded machines and workstations. Windows 8 was designed “for the world we know, in which most computers are mobile.” He added that today they would add another piece to the Windows 8 story. People want to use Windows without compromise, right? When Ballmer joined Microsoft in 1980, their number one product by revenue was a hardware product.

Microsoft has released lots of hardware. Mice. Keyboards. The Xbox. Kinect.

Then he dropped this: “We believe that any intersection between human and machine can be made better when every aspect of the experience, hardware and software, are considered together.” The example he shared was Xbox with Kinect.

More PCs will be delivered in 2013 than any previous year. According to the IDC, that will be 375 million units.

And then … bang! “Something new, something different.”

Yes, there will be a new family of computing devices from Microsoft.

Remember Microsoft Surface? Now Microsoft is releasing the Microsoft Surface tablet.

gallery_4_large

The tablet is 9mm thick when you get the ARM version, and 13mm thick when you go for the more powerful “Pro” version. It is less than 1 1/2 pounds and sports a 10.6” ClearType HD display with Gorilla Glass 2 (that means it’s scratch-resistant). Up to 128 GB solid state drives. USB 2.0 (3.0 in the Pro version). There is a built-in stand that is less than the thickness of a credit card and a magnetic cover that turns into a keyboard.

How cool is that?

It’s a pretty exciting announcement. To me, it’s not about what Microsoft is releasing, however. Unlike Apple, Microsoft releases Windows 8 to OEMs who can build their own hardware. This means more innovation from other companies and the opportunity to see tablets that are even more innovative than ever before.

Go check it out at the new official website: http://www.surface.com/ and I’ll continue to post coverage as more hands-on videos, blog posts, and links surface on my Windows 8 page you can visit by clicking here.

Friday, June 8, 2012

Compressing Data in Windows 8 Metro Applications

The following post is an excerpt from Chapter 6 of my upcoming book, Designing Windows 8 Metro Applications with C# and XAML. Keep reading to learn how you can receive a free copy of the full chapter.

Storing large amounts of data can take up a large amount of disk space. Data compression encodes information in a way that reduces its overall size. There are two general types of compression. Lossy compression may not preserve all of the original information and is often used in image, video, and audio compression. Lossless compression preserves the full fidelity of the original data set.

The Windows 8 runtime exposes the Compressor and Decompressor classes for compression. The Compression project provides an active example of compressing and decompressing a data stream. The project contains a text file that is almost 100 kilobytes in size. It loads that text and displays it with a dialog showing the total bytes. You can then click a button to compress the text, and click another button to decompress it back.

The compression task performs several tasks. A local file is open for output to store the result of the compressed text. There are various ways to encode text, so it first uses the Encoding class to convert the text to a UTF8 encoded byte array:

var storage = await ApplicationData.Current.LocalFolder
   .CreateFileAsync("compressed.zip", 
   CreationCollisionOption.ReplaceExisting);
var bytes = Encoding.UTF8.GetBytes(_text);

You learned earlier in this chapter how to locate the folder for a specific user and application. You can examine the folder for the sample application to view the compressed file after you click the button to compress the text. The file is saved with a zip extension to illustrate that it was compressed, but it doesn’t contain a true archive so you will be unable decompress the file from Explorer.

The next lines of code open the file for writing, create an instance of the Compressor and write the bytes. The code then completes the compression operation and flushes all associated streams.

var stream = await storage.OpenStreamForWriteAsync();
var compressor = new Compressor(stream.AsOutputStream());
await compressor.WriteAsync(bytes.AsBuffer());
await compressor.FlushAsync();
await compressor.FinishAsync();
await stream.FlushAsync();

Once the compression operation is complete, the bytes are read back from disk to save and to show the compressed size. You’ll find the default algorithm cuts the text file down to almost half of its original size. The decompression operation uses the Decompressor class to perform the reverse operation and retrieve the decompressed bytes in a buffer (it then saves these to disk so you can examine the result).

var decompressor = new Decompressor(stream.AsInputStream());
var bytes = new Byte[100000];
var buffer = bytes.AsBuffer();
var buf = await decompressor.ReadAsync(buffer, 999999, 
   InputStreamOptions.None);

When you create the classes for compression you can pass a parameter to determine the compression algorithm that is used. Table 6.4 lists the possible values.

Table 6.4: Compression Algorithms

CompressAlgorithm Member

Description

InvalidAlgorithm

Invalid algorithm. Used to generate exceptions for testing.

NullAlgorithm

No compression is applied and the buffer is simply passed through. Used primarily for testing.

Mszip

Uses the MSZIP algorithm.

Xpress

Uses the XPRESS algorithm.

XpressHuff

Uses the XPRESS algorithm with Huffman encoding.

Lzms

Uses the LZMS algorithm.

The Windows Runtime makes compression simple and straightforward. Use compression when you have large amounts of data to store and are concerned about the amount of disk space your application requires. Experiment to find the algorithm that provides the best compression ratio for the type of data you are storing and remember that you must pass the same algorithm to the decompression routine that you used to compress the data.

This excerpt is from Chapter 6, “Data” from my upcoming book, Designing Windows 8 Metro Applications with C# and XAML. The full chapter covers topics including application settings, local and roaming storage, serialization, async and await, IO helpers available in the Windows Runtime, accessing embedded resources, dealing with collections, loading content from the web (including web pages and syndicated feeds), streams, buffers, byte arrays, compression, encryption, and signing. If you’re interested, there are two ways you can get access to this chapter next week:

1. Attend one of my Codestock Sessions next week and receive a free hard copy of the chapter.

2. Visit the Wintellect booth at TechEd and have your badge scanned. You will receive a PDF copy of the full chapter.

If you’re interested in early access to the book (you’ll be able to read chapters even before they are edited and technically reviewed, so that you can provide insights and request additional content as I am writing it) you can obtain a copy through Safari Rough Cuts. Thanks!