Windows Apps JumpStart Publish Hack

Don’t forget, if you can get to London on Saturday September 20th, come to our Publish Hack at Microsoft’s Cardinal Place offices near Victoria Station and get your app published to store! Our goal for this day is to make it a fun, informal day where you can overcome those last blockers and issues that are preventing you getting over those last yards to publication. There will be fun, and pizza, and beer….oh, yes – and prizes!

We will have experts from Microsoft and from the developer community there to help you, including elite Windows App engineers from our App Consult program.

Did I mention prizes? Yes, as if the fun of taking part wasn’t enough, we’re going to give you additional incentive to take part by offering prizes, including:

- Nokia Lumia 1020 phones

- Nokia Lumia 1520 phablets

- Nokia Contactless Charging units

- Arc Mice

- Arc Keyboards

- A Goodie bag for every single developer that publishes an app on the day!

The prizes will be awarded for quality, progress made and for good old-fashioned sweat and tears.

Details and registration page:

Windows Apps JumpStart Publish Hack
Saturday 20 Sep – 9AM – 9PM
http://aka.ms/winappspublishhack 

Hope you can come along!

Windows Apps JumpStart LIVE Events Series

We’re starting a new series of events for UK developers that will help you on the journey from initial interest in developing apps for Windows 8 and Windows Phone right the way through to publishing an app to the Windows Store. You can join into the series at whichever point makes sense to you, so whether you’ve never opened Visual Studio before or written a line of C#, or you’re a developer who has already written software using out tools and languages but are new to apps, we can help you get to that point where you’re publishing your first app into our store. And we’re going to repeat the series of events every quarter, so you can jump on and off the series and attend events at whatever pace makes sense to you.

We start with two one-hour webinars run back-to-back:

Webinar 1: Windows Apps JumpStart LIVE Series – Kick Starter Webinar for the non C#/XAML developer: This one hour webinar is aimed at developers who are completely new to Visual Studio, XAML, C# and .NET. This will give you what they need to get started with downloading Visual Studio, a little bit of knowledge of C# and the structure of a XAML-based app.

Webinar 2: Windows Apps JumpStart LIVE Series – JumpStart Webinar: Building Apps with C# and XAML: This one hour webinar follows on straight away after the previous one. It is aimed at developers who are new to Windows Store app development, but who have some experience of developing software using .NET, or for those who have attended the previous webinar.

Following on from the webinars, we have a one-day dev camp:

Dev camp: Windows Apps JumpStart LIVE Series: Windows Apps Dev Workshop
This one day event will be help at Microsoft’s offices near Victoria Station, London, running 9:30 – 18:00. At this workshop, you will learn how to program Windows and Windows Phone apps, including universal apps that run on both. There will be Hands-on Labs available, and you can get tips and advice from Microsoft experts and from peers in the developer community.

And following on from that, we have a one-day Publish hackathon:

Publish event: Windows Apps JumpStart LIVE Series: Publish Hackathon
This informal one-day event will also be held at Microsoft’s building in London, running 9:00 – 21:00 on a Saturday. This is a fun 12 hour event encouraging developers to bring their existing projects (apps/cloud projects) to polish and publish through to the last mile with help from Microsoft and community experts.

First events are coming up fast!:

Come along and join us – and if not this quarter, remember we are repeating these events throughout the year so you can join us when you can!

Windows Apps JumpStart LIVE Events Series

We’re starting a new series of events for UK developers that will help you on the journey from initial interest in developing apps for Windows 8 and Windows Phone right the way through to publishing an app to the Windows Store. You can join into the series at whichever point makes sense to you, so whether you’ve never opened Visual Studio before or written a line of C#, or you’re a developer who has already written software using out tools and languages but are new to apps, we can help you get to that point where you’re publishing your first app into our store. And we’re going to repeat the series of events every quarter, so you can jump on and off the series and attend events at whatever pace makes sense to you.

We start with two one-hour webinars run back-to-back:

Webinar 1: Windows Apps JumpStart LIVE Series – Kick Starter Webinar for the non C#/XAML developer: This one hour webinar is aimed at developers who are completely new to Visual Studio, XAML, C# and .NET. This will give you what they need to get started with downloading Visual Studio, a little bit of knowledge of C# and the structure of a XAML-based app.

Webinar 2: Windows Apps JumpStart LIVE Series – JumpStart Webinar: Building Apps with C# and XAML: This one hour webinar follows on straight away after the previous one. It is aimed at developers who are new to Windows Store app development, but who have some experience of developing software using .NET, or for those who have attended the previous webinar.

Following on from the webinars, we have a one-day dev camp:

Dev camp: Windows Apps JumpStart LIVE Series: Windows Apps Dev Workshop
This one day event will be help at Microsoft’s offices near Victoria Station, London, running 9:30 – 18:00. At this workshop, you will learn how to program Windows and Windows Phone apps, including universal apps that run on both. There will be Hands-on Labs available, and you can get tips and advice from Microsoft experts and from peers in the developer community.

And following on from that, we have a one-day Publish hackathon:

Publish event: Windows Apps JumpStart LIVE Series: Publish Hackathon
This informal one-day event will also be held at Microsoft’s building in London, running 9:00 – 21:00 on a Saturday. This is a fun 12 hour event encouraging developers to bring their existing projects (apps/cloud projects) to polish and publish through to the last mile with help from Microsoft and community experts.

First events are coming up fast!:

Come along and join us – and if not this quarter, remember we are repeating these events throughout the year so you can join us when you can!

Windows Phone 8.1 Jump Start is coming!

I’m pleased to announce that the registration page is now up for this year’s Windows Phone Jump Start!

Building Apps for Windows Phone 8.1 Jump Start will be held on 29th, 30th April and extend onto the morning of May 1st. As it says on the website: “If you’re an app developer who wants to design and build Windows Phone 8.1 apps using XAML and C#, don’t miss this exciting event. The two-and-a-half day, demo-rich course, taught by experts who have years of experience developing (and writing about the process), focuses on how to create apps for Windows Phone 8.1 in Visual Studio and how to create universal app projects that share a high percentage of code and that target both Windows and Windows Phone.”

This time around, the Jump Start is structured into 4 main parts:

Section 1: Introduction

· Session 1: Introduction to Windows Phone 8.1 (50 minutes)
Overview of the Windows Phone 8.1 developer platform, including guidance on the choices of app framework now available.

Section 2: Building Windows Runtime Apps using XAML and C#

Sessions that show how to build phone apps using WinRT XAML

· Session 2: Getting Started Building Windows Runtime Apps (50 minutes)
Fundamentals of building a WinRT XAML app for a Phone target, introducing the controls, layout, styles and theme resources, AppBar, StatusBar.

· Session 3: Page Navigation and Data Binding (25 minutes)
Navigating between pages in a Windows Runtime app, page caching and data binding

· Session 4: Lists and List Items (50 minutes)
Programming Lists, formatting list items and handling long or complex lists effectively

· Session 5: Windows Runtime App Page Layout Controls (25 minutes)
Pivot, Hub and Single Page layouts.

· Session 6: Adapting UI for Different Screens (25 minutes)
Explain the new layout system, and how to ensure your UI adapts to different phone screen sizes and orientations.

· Session 7: Windows Runtime App Lifecycle (25 minutes)
Explain the ways apps can be started, terminated and resumed.

· Session 8: Localization and Globalization in Windows Runtime Apps (25 minutes)
Making your app world-ready

Section 3: Programming Windows Runtime Platform Features (Windows Runtime XAML and Silverlight 8.1)

Programming platform features in Windows Phone 8.1 apps from either Windows Runtime Apps or Windows Phone Silverlight Apps 

· Session 9: Data Storage, Backup and Roaming (50 minutes)
All about storing data, backing app data up to the cloud and roaming data across devices

· Session 10: Contracts and Sharing Files and Data (50 minutes)
Share contract, FileOpenPicker/FileSavePicker, File & Uri associations

[Day 2]

· Session 11: Background Tasks (25 minutes)
How to run code in the background

· Session 12: Maps, Geolocation and Geofencing (25 minutes)
Maps, Location and GeoFencing

· Session 13: Networking, Mobile Services and Authentication (50 minutes)
Networking fundamentals. Includes Background Transfer Service and Web Authentication Broker 

· Session 14: Tiles, badges and toasts and Notification Center (50 minutes)
Tiles and toasts and Notification Center

· Session 15: Sensors and Proximity: NFC and Bluetooth (25 minutes)
Sensors, NFC and Bluetooth

· Session 16: Contacts and Calendar (25 minutes)
WinRT APIs for Contacts and Calendar, plus new capabilities (available on phone only) for Wallet-aware apps

· Session 17: Camera, Media, Audio and Speech (50 minutes)
Working with the camera, media and video editing

· Session 18: Enterprise LOB Apps (50 minutes)
All the new features aimed at Enterprise LOB and MDDM

· Session 19: SQLite Database (25 minutes)
How to program SQLite

· Session 20: VS Tooling and Memory Profiling (25 minutes)
Introduction to the many tools built into Visual Studio to help you develop Windows apps

[Day 3]

· Session 21: App Packaging and Publication (50 minutes)
How to package your app and get your app published in the Store

· Session 22: Best practices: Building Universal Apps for Windows Phone and Windows (50 minutes)
Guidance for building for both

Section 4: Upgrading Windows Phone Silverlight 8.0 apps to Silverlight 8.1

Programming new platform features from a Silverlight app

· Session 23: Upgrading Windows Phone Silverlight 8.0 Apps to Silverlight 8.1 (50 minutes)
Recap on why you would use Silverlight, and explanation of what issues must be considered when upgrading to Silverlight 8.1. Topics include behavioural changes introduced by the quirks API, Lifecycle changes as FAR is now the only mode of reactivation, implementing share contract and using the FileOpenPicker/FileSavePicker, Web Authentication Broker, moving from MPNS to WNS, background agents alongside background tasks.

Hope you can join us for the live event.  The event is happening in Redmond and will be from 9:00am – 5:00pm Pacific Daylight Time. We realize that doesn’t make it the most convenient timeslots for everyone, but if you can’t watch it all, we hope you will join us when you can, and then catch up with the full list of sessions when the videos are posted on Channel9 shortly after!

Registration page can be found here!

SQLiteWinRT: Opening databases shipped as app content or from an SD Card

Recently, I was asked about opening a database file inserted into a device on an SD card. I had to make a slight change to the SQLWinRT wrapper to enable it, so this post explains how, and also looks at opening databases shipped in the app package as content.

Opening databases shipped as content

You can include a prepopulated SQLite database in your Windows 8.x or Windows Phone app package. When the user installs the app, the database file ends up in the App Install folder where you can open it from your code – but only in a read-only fashion:

public static async void LoadDatabase()
{
    // Get a reference to the SQLite database
    db = new SQLiteWinRT.Database(
        Windows.ApplicationModel.Package.Current.InstalledLocation, 
        "customers.sqlite");

    await db.OpenAsync(SQLiteWinRT.SqliteOpenMode.OpenRead);

    // PRAGMA temp_files=2 causes temporary files to be created in memory
    // rather than in a physicalfile in the same folder as the database
    // Note that temp files only really get used if you are going to do 
    // complicated JOINs etc
    await db.ExecuteStatementAsync("PRAGMA temp_files=2");
}

If you want to have read-write access to the database, you must copy it from the install folder to the local folder first.

async Task CopyDatabaseAsync()
{
    // Has the database been copied already?
    try
    {
        await ApplicationData.Current.LocalFolder.GetFileAsync("customers.sqlite");
        // No exception? It exists...
        return;
    }
    catch (System.IO.FileNotFoundException)
    {   // Expected response - no-op 
    }

    StorageFile dbfile = await StorageFile.GetFileFromApplicationUriAsync(
        new Uri("ms-appx:///customers.sqlite"));
    await dbfile.CopyAsync(ApplicationData.Current.LocalFolder);
}

Opening a Database on an SD Card

A database file that you open from an SD Card is related to the previous case in that it is read-only. You cannot write to any file on an SD Card from any app in Windows Phone 8.

I haven’t researched it thoroughly, but you should be able to open a database file on removable storage in a Windows 8.x Store app. You will have to request the Removable Storage capability in the app manifest, and declare the file extensions you want to access in the app manifest as well. Then you should be able to get a StorageFile reference to the database file using techniques similar to those discussed here: http://lunarfrog.com/blog/2012/10/27/external-storage-devices/   . When I’ve tried it, I’ll update this post!

What I have tried though, is doing this on a Windows Phone 8 device that has an SD card slot, such as the Nokia Lumia 820. As with Windows 8, you have to declare the file extensions you want to access in the manifest. For example, add the following after the closing </Tokens> tag:

    <Extensions>
      <FileTypeAssociation Name="sqlite" TaskID="_default" NavUriFragment="fileToken=%s">
        <SupportedFileTypes>
          <FileType ContentType="application/sqlite">.sqlite</FileType>
        </SupportedFileTypes>
      </FileTypeAssociation>
    </Extensions>

Then in your code, you can open a read-only connection to the database as follows:

public static async void LoadDatabase()
{
    // Get a reference to the SQLite database
    ExternalStorageDevice _sdCard = 
        (await ExternalStorage.GetExternalStorageDevicesAsync())
        .FirstOrDefault();

    if (_sdCard == null)
    {
        MessageBox.Show("No SD Cards found");
        return;
    }
    else
    {
        ExternalStorageFile dbStoragefile = 
            await _sdCard.GetFileAsync("customers.sqlite");
        db = new SQLiteWinRT.Database(dbStoragefile.Path);
    }

    await db.OpenAsync(SQLiteWinRT.SqliteOpenMode.OpenRead);

    // PRAGMA temp_files=2 causes temporary files to be created in memory
    // rather than in a physicalfile in the same folder as the database 
    // Note that temp files only really get used if you are going to do 
    // complicated JOINs etc
    await db.ExecuteStatementAsync("PRAGMA temp_files=2");
}

Important: I had to modify the wrapper code posted up on http://sqlwinrt.codeplex.com in order to enable this usage. I added a new override of the Database object constructor that just takes the path to the database file as a string. Earlier versions had one override of the constructor that took a Windows.Storage.StorageFile parameter and another that took a Windows.Storage.StorageFolder and the filename as string, but neither of those were usable since the ExternalStorageFile object is not as you might expect a derivative of Windows.Storage.StorageFile, but is instead in the Microsoft.Phone.Storage namespace – hence I had to create a new constructor.

Download the latest version of the wrapper code from http://sqlwinrt.codeplex.com to get this update – note that this is built against SQLite version 3.8.2 – make sure you update to this version using the Visual Studio – Tools – Extensions and Updates wizard.

Download the sample project here

Note that it covers both scenarios covered in this post. At the top of app.xaml.cs there is a compile time symbol #define USE_SDCARD – comment this out to test the ‘database shipped as content’, or leave it in to test the SD card access. You’ll need a real device for the latter and before testing the app use your PC to copy the customers.sqlite file from the project onto the sd card and insert into your phone. Sadly, the emulator does not emulate a removable storage card!

NDC London 2013

I just spent 3 enjoyable days at the NDC conference in London. NDC usually stands for Norwegian Developer Conference which happens every June in Oslo, Norway and which is a popular conference – I really hope that I can speak there next June! The organisers of that, NDC Conferences, decided to bring their show to London – hence this weeks’ show – with NDC modified slightly to stand for ‘New Developer’s Conference’

And what a show! – great speakers, great food, large, comfortable venue, loads of sessions and an awesome party. Congratulations to NDC for putting on a great event, and I look forward to supporting them in future years.

My own contribution was two sessions: Windows Phone Networking Toolkit which was an update of a session I gave at TechEd this year, and which works through various topics related to effective network programming on Windows Phone, and Creating Killer Windows Phone Apps, a brand new session looking at ways to improve the quality of your apps. That went well and I look forward to repeating it somewhere soon. It looks at correct use of the animations in the Windows Phone Toolkit, programming Push Notifications using Windows Azure Notifications Hubs, localizing your app with the Multilingual Toolkit and reducing your memory footprint to improve your apps performance on low memory devices.

The slides for the sessions are available here:

How to massively improve SQLite Performance (using SqlWinRT)

Use ConfigureAwait(false) on calls to SqlWinRT async methods to improve INSERT performance up to 145 times, and SELECT performance up to 80 times 

Sample project: SQLitePerformance.zip

I have been seeing a few comments by people complaining of poor performance when executing SELECT statements against a SQLite database using the SQLWinRT wrapper, or when adding new records using multiple consecutive INSERT statements.

With many relational databases, poor performance on INSERT can often be rectified just by wrapping all your operations within a single transaction. If you don’t explicitly declare a transaction when programming against SQLite, the database engine creates an implicit transaction for each statement execution and that has an overhead associated with it, so by wrapping all your INSERTs inside a single transaction, you would expect a performance boost.

With SELECT operations, poor performance is often just down to not having the correct keys defined. If you have a statement such as SELECT * FROM CUSTOMER WHERE NAME = ‘CONTOSO’ and you execute it on a database where you have not defined a key on the NAME column, the only way the database engine can find the required record is to start at the first record and read sequentially down the table until it reaches the end in order to select the rows to return (called a ‘Table Scan’). If you simply want to select all the records in a table (SELECT * FROM CUSTOMER), then you can’t avoid the Table Scan – in fact that’s what you want – so you would expect that there wasn’t very much you could do to improve performance in that case.

Well – that’s the theory. I set about building a simple demo to demonstrate these points, but it didn’t turn out quite how I expected! It turns out that, important though the points already mentioned are, the most important factor BY FAR is how you call the async methods of the SQLWinRT API! Read on…

The Test Program

For my test program, I was inspired by this post on Stack Overflow: How do I improve the performance of SQLite. That post is quite old and is talking about C++ dev, so not directly relevant to Windows Phone or Windows Store app development using managed code, but I liked the test case, which was to take a large dataset from the City of Toronto’s publically available transportation data. Unfortunately, the exact same dataset used in the original post isn’t available anymore, so I couldn’t do a direct comparison, but they did have the Transportation Trips dataset, containing 128982 records that we can first insert into a SQLite database, and then select them out again.

SQLite Bulk Insert

The dataset is in the form of a CSV text file, representing 128982 rows, each containing 8 columns. The code to read the file and extract the values  looks like this:

SQLiteWinRT.Database db;

private async void Button_Start_Click(object sender, RoutedEventArgs e)
{
    int Route_ID;
    int Service_ID;
    int Trip_ID;
    string Trip_Headsign;
    int Direction_ID;
    int Block_ID;
    int Shape_ID;
    bool Wheelchair_Accessible;

    Button_Start.IsEnabled = false;

    /*********************************************/
    /* Open the Database and create the Schema */
    await LoadDatabase();

    Stopwatch sw = Stopwatch.StartNew();
    int n = 0;

    // Prepare statement
    using (var statement = await db.PrepareStatementAsync(
        @"INSERT INTO TTC (id, Route_ID, Service_ID, Trip_ID, 
                           Trip_Headsign, Direction_ID, Block_ID, 
                           Shape_ID, Wheelchair_Accessible) 
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"))
    {
        // Start transaction
        await db.ExecuteStatementAsync("BEGIN TRANSACTION");

        /*********************************************/
        /* Open input file and import into Database*/
        var inputfile = await Windows.ApplicationModel.Package.Current.
            InstalledLocation.GetFileAsync("trips.txt");
        using (var inputStream = await inputfile.OpenSequentialReadAsync())
        {
            using (StreamReader rdr = 
                new StreamReader(inputStream.AsStreamForRead()))
            {
                while (true)
                {
                    string inputline = await rdr.ReadLineAsync();
                    if (inputline == null)
                        break;

                    // Discard line 0 - header line
                    if (n > 0)
                    {
                        string[] fields = inputline.Split(new char[] { ',' });

                        Route_ID = Int32.Parse(fields[0]); ;
                        Service_ID = Int32.Parse(fields[1]);
                        Trip_ID = Int32.Parse(fields[2]);
                        Trip_Headsign = fields[3];
                        Direction_ID = Int32.Parse(fields[4]);
                        Block_ID = Int32.Parse(fields[5]);
                        Shape_ID = Int32.Parse(fields[6]);
                        Wheelchair_Accessible = fields[7] == "1" ? true : false;

                        /* Bind parameter values and Insert */
                        statement.Reset();
                        statement.BindIntParameterAt(1, n);
                        statement.BindIntParameterAt(2, Route_ID);
                        statement.BindIntParameterAt(3, Service_ID);
                        statement.BindIntParameterAt(4, Trip_ID);
                        statement.BindTextParameterAt(5, Trip_Headsign);
                        statement.BindIntParameterAt(6, Direction_ID);
                        statement.BindIntParameterAt(7, Block_ID);
                        statement.BindIntParameterAt(8, Shape_ID);
                        statement.BindIntParameterAt(9, Wheelchair_Accessible ? 1 : 0);

                        await statement.StepAsync();
                    }

                    n++;

                    if (n % 100 == 0)
                    {
                        progressBar.Value = n;
                    }
                }
            }
        }

        // Commit transaction
        await db.ExecuteStatementAsync("COMMIT TRANSACTION");
    }

    db.Dispose();
    db = null;

    var report = String.Format(
        "Inserted {0:d} records in {1:0.00} seconds", 
        n - 1, 
        (double)sw.ElapsedMilliseconds / 1000);
    MessageBox.Show(report);

    Button_Start.IsEnabled = true;
}

private async Task LoadDatabase()
{
    db = new SQLiteWinRT.Database(
        ApplicationData.Current.LocalFolder, "sqliteperf.db");

    await db.OpenAsync();

    string sql = @"
        CREATE TABLE IF NOT EXISTS TTC 
            (id INTEGER PRIMARY KEY, 
                Route_ID INTEGER, 
                Service_ID INTEGER, 
                Trip_ID INTEGER, 
                Trip_Headsign TEXT,
                Direction_ID INTEGER, 
                Block_ID INTEGER, 
                Shape_ID INTEGER, 
                Wheelchair_Accessible BOOL)";

    await db.ExecuteStatementAsync(sql);
}

Using this code, and by commenting out lines here and there as appropriate, we can test three scenarios:

  • Processing the input file but not inserting records in the database (this just gives us the time for the file processing)
  • Uncomment the call to StepAsync() to Insert each record into the database individually
  • Uncomment the lines executing the BEGIN TRANSACTION, END TRANSACTION statements so all records are inserted inside a single transaction

testrunner  Transaction

And the results? Well, not great, to be honest:

Test Total Time (seconds) – 128982 records Insert Time per record (ms)
Process records – no insert 7 -
Insert records individually 6307 49
Insert records within a containing transaction 3177 25

Although wrapping all the inserts into a single transaction halves the time it takes to insert the 128982 records compared to separate operations (where the database engine will activate an implicit transaction for every insert), we are still only getting 25ms per insert, or 40 operations per second. That’s not too impressive.

Trying ConfigureAwait(false)

Those performance figures are disappointing and make bulk insert operations in a Windows Phone or Windows Store app impractical. However, look what happens when we make a subtle change to the main loop of code:

Stopwatch sw = Stopwatch.StartNew();
int n = 0;

// Prepare statement
using (var statement = await db.PrepareStatementAsync(
    @"INSERT INTO TTC (id, Route_ID, Service_ID, Trip_ID, Trip_Headsign, 
                        Direction_ID, Block_ID, Shape_ID, Wheelchair_Accessible) 
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"))
{
    // Start transaction
    await db.ExecuteStatementAsync("BEGIN TRANSACTION");

    /*********************************************/
    /* Open input file and import into Database*/
    var inputfile = await Windows.ApplicationModel.Package.Current.
        InstalledLocation.GetFileAsync("trips.txt");
    using (var inputStream = await inputfile.OpenSequentialReadAsync())
    {
        using (StreamReader rdr = new StreamReader(inputStream.AsStreamForRead()))
        {
            while (true)
            {
                string inputline = await rdr.ReadLineAsync();
                if (inputline == null)
                    break;

                // Discard line 0 - header line
                if (n > 0)
                {
                    string[] fields = inputline.Split(new char[] { ',' });

                    Route_ID = Int32.Parse(fields[0]); ;
                    Service_ID = Int32.Parse(fields[1]);
                    Trip_ID = Int32.Parse(fields[2]);
                    Trip_Headsign = fields[3];
                    Direction_ID = Int32.Parse(fields[4]);
                    Block_ID = Int32.Parse(fields[5]);
                    Shape_ID = Int32.Parse(fields[6]);
                    Wheelchair_Accessible = fields[7] == "1" ? true : false;

                    /* Bind parameter values and Insert */
                    statement.Reset();
                    statement.BindIntParameterAt(1, n);
                    statement.BindIntParameterAt(2, Route_ID);
                    statement.BindIntParameterAt(3, Service_ID);
                    statement.BindIntParameterAt(4, Trip_ID);
                    statement.BindTextParameterAt(5, Trip_Headsign);
                    statement.BindIntParameterAt(6, Direction_ID);
                    statement.BindIntParameterAt(7, Block_ID);
                    statement.BindIntParameterAt(8, Shape_ID);
                    statement.BindIntParameterAt(9, Wheelchair_Accessible ? 1 : 0);

                    await statement.StepAsync().AsTask().ConfigureAwait(false);
                }

                n++;
                if (n % 100 == 0)
                {
                    Dispatcher.BeginInvoke(()=>progressBar.Value = n);
                }
            }
        }
    }

    // Commit transaction
    await db.ExecuteStatementAsync("COMMIT TRANSACTION");
}

db.Dispose();
db = null;

Dispatcher.BeginInvoke(() =>
    {
        var report = String.Format(
            "Inserted {0:d} records in {1:0.00} seconds", 
            n - 1, (double)sw.ElapsedMilliseconds / 1000);
        MessageBox.Show(report);

        Button_Start.IsEnabled = true;
    });
}

The main – and significant change above – is that the StepAsync() method is now called in a different way:

await statement.StepAsync().AsTask().ConfigureAwait(false);

In addition, the code that ‘touches’ the UI, such as the MessageBox.Show() call, and the code setting the ProgressBar is now called using Dispatcher.BeginInvoke(Action a). This is necessary because the change to how StepAsync() is called has a knock-on effect of causing the code to end up executing on a background thread – I will explain more on this shortly.

What does this do to the timings?:

Test Total Time (seconds) – 128982 records Insert Time per record (ms)
Process records – no insert 7 -
Insert records individually 6307 49
Insert records within a containing transaction 3206 25
Insert individually with ConfigureAwait(false) 2791 21
Insert within a transaction with ConfigureAwait(false) 55 0.43

TransactionWithConfigureAwait

WHOA! What happened there? If you insert records within a transaction and use ConfigureAwait(false), you can achieve insert performance of one insert every 0.43 ms, or 2345 records per second. Now we’re talking! That means the performance of inserting records individually without using ConfigureAwait(false) is more than 144 times slower than the best case.

Why such a dramatic improvement? Well, the Task.ConfigureAwait(bool continueOnCapturedContext) method is used to configure the awaiter used to await the result of the asynchronous operation. An awaiter is an object you don’t see or program directly as a developer, but simply by using the await keyword when calling an asynchronous method, the compiler will generate code that uses an awaiter to handle the suspension and reactivation of your calling method while it waits for some asynchronous operation to complete. When the asynchronous method has completed, the awaiter resumes execution of your code which by default happens on the same context (think ‘thread’) you were on when you called the async method. But if you set ConfigureAwait(false), it doesn’t do that but instead continues on whatever context the async method executed on. There’s a performance advantage to this, which is why the advice to authors of library code is that you should always make async calls within your library code using ConfigureAwait(false) – the caller of your library method can then make the decision on whether to return to their original context by choosing whether or not to use ConfigureAwait(false) on the call to your async library method.

Which is what we are doing here – by setting ConfigureAwait(false) on our call to SqlWinRT:Statement.StepAsync() we are saying “don’t bother continue on the originating context, stay on whatever context you are executing on”. And as you can see, the performance gain is spectacular! To be honest, I was very surprised just how spectacular the performance improvement is. Normally, you would expect a modest performance gain, but I guess that because this call is happening between managed code and a WinRT component, the overhead of ConfigureAwait(true) - the default – is particularly significant.

One consequence of using ConfigureAwait(false) is that our code after the await call resumes on a background thread, so when we want to interact with the UI, such as to set the ProgressBar or to display the message at the end, we have to use the Dispatcher to make sure the code that touches the UI executes back on the UI thread:

Dispatcher.BeginInvoke(() =>
    {
        var report = String.Format("Inserted {0:d} records in {1:0.00} seconds", 
            n, (double)sw.ElapsedMilliseconds / 1000);
        MessageBox.Show(report);

        Button_Start.IsEnabled = true;
    });

If we don’t do that, you get an exception.

SELECT Performance

What about the performance of reading records out of the database? The warnings I gave in the introduction to this piece about having appropriate keys configured if you are doing a SELECT with a filter on a column that is not the primary key are still valid. But even if you are simply reading all the records out of a table, whether you use ConfigureAwait(false) again has a huge impact.

Here’s the code you would probably write to read all the rows in our table and to load them into in-memory objects in an ObservableCollection<T> ready to display on the UI:

private async void Button_Select_Click(object sender, RoutedEventArgs e)
{
    if (db == null)
    {
        db = new SQLiteWinRT.Database(
            ApplicationData.Current.LocalFolder, "sqliteperf.db");

        await db.OpenAsync();
    }


    Stopwatch sw = Stopwatch.StartNew();
    int n = 0;
    Button_Select.IsEnabled = false;

    string sql = @"
        SELECT
            id , 
                Route_ID , 
                Service_ID, 
                Trip_ID, 
                Trip_Headsign,
                Direction_ID, 
                Block_ID, 
                Shape_ID, 
                Wheelchair_Accessible
            FROM TTC";
    var stmt = await db.PrepareStatementAsync(sql);

    ObservableCollection<TransportationTrip> tripCollection =
        new ObservableCollection<TransportationTrip>();

    while (await stmt.StepAsync())
    {
        var trip = new TransportationTrip()
        {
            ID = stmt.GetIntAt(0),
            RouteID = stmt.GetIntAt(1),
            ServiceID = stmt.GetIntAt(2),
            TripID = stmt.GetIntAt(3),
            TripHeadsign = stmt.GetTextAt(4),
            DirectionID = stmt.GetIntAt(5),
            BlockID = stmt.GetIntAt(6),
            ShapeID = stmt.GetIntAt(7),
            WheelchairAccessible = 
                stmt.GetIntAt(8) == 1 ? true : false,
        };

        tripCollection.Add(trip);
        n++;
    }

    var report = String.Format("Selected {0:d} records in {1:0.00} seconds",
        n, (double)sw.ElapsedMilliseconds / 1000);
    MessageBox.Show(report);

    Button_Select.IsEnabled = true;
}

Running this gives the following result:

SELECT-no-Await

2838 seconds! That sucks – big time.

Then do it again, but make these subtle changes:

while (await stmt.StepAsync().AsTask().ConfigureAwait(false))
{
    var trip = new TransportationTrip()
    {
        ID = stmt.GetIntAt(0),
        RouteID = stmt.GetIntAt(1),
        ServiceID = stmt.GetIntAt(2),
        TripID = stmt.GetIntAt(3),
        TripHeadsign = stmt.GetTextAt(4),
        DirectionID = stmt.GetIntAt(5),
        BlockID = stmt.GetIntAt(6),
        ShapeID = stmt.GetIntAt(7),
        WheelchairAccessible = stmt.GetIntAt(8) == 1 ? true:false,
    };

    tripCollection.Add(trip);
    n++;
}

Dispatcher.BeginInvoke(() =>
    {
        var report = String.Format("Selected {0:d} records in {1:0.00} seconds", 
            n, (double)sw.ElapsedMilliseconds / 1000);
        MessageBox.Show(report);

        Button_Select.IsEnabled = true;
    });

Which gives this result:

SELECT-await

That’s some improvement! Comparing the two:

Test Total Time (seconds) – SELECT 128981 records SELECT Time per record (ms) Records per second
SELECT 2838 22 45
SELECT with ConfigureAwait(false) 32.4 0.25 3980

That’s a huge improvement!

[WARNING: The timings quoted here are for running on the emulator. You should expect times on a real device to be very substantially slower.]

Conclusions

Some golden rules emerge from this:

  1. Use ConfigureAwait(false) when calling SqlWinRT async methods, particularly within repetitive looping such as INSERT or SELECT of a significant number of records. Remember that when you do so, your code will not resume on the same context it started on, so take appropriate measures to handle this.
  2. In addition to using ConfigureAwait(false), wrap large numbers of INSERTs in a single transaction to get the best performance.

The last learning from this is not specific to SqlWinRT: if you call async methods on a WinRT component, there is a significant overhead in switching back to the originating context. Try calling such a component using ConfigureAwait(false) – it may yield significant performance benefits.

Lastly – this was a test program. If you ever find yourself trying to read 128000 records into memory, I would suggest you have another think about your app design and whether you really need all those objects in memory Smile .

SQLiteWinRT: Now BLOB columns and Windows 8.1 supported

I’ve posted some updates to the SQLite WinRT API at http://sqlwinrt.codeplex.com. The SQLite WinRT API offers lightweight Windows Runtime (WinRT) APIs you can use to access the most common SQLite database functionality by using SQL statements, rather than a LINQ-style API.

Support for Windows 8.1

One change is to add an implementation for Windows 8.1. So if you download the source code now (there’s no msi or NUGet package for this as yet), you’ll get three projects which are the WinRT components for Windows 8.0, Windows 8.1 and Windows Phone 8.0. Make sure you have installed the SQLite SDK for your target platform on the Tools – Extensions and Updates menu and then Just include the appropriate project in your own solution, and you’re good to go. See my earlier post for an introduction to programming with the API: http://andywigley.com/2013/06/06/sqlite-winrt-database-programming-on-windows-phone-and-windows-8/

Namespaces Standardised

The other relatively minor change is that I’ve standardised the namespace used to SQLWinRT for all platforms. It just makes it a little easier to share code across platforms that way. That does mean that the blog post referenced in the previous paragraph shows code using the old SQLiteWinRTPhone namespace – though the sample accompanying that post has been updated.

Support for BLOB columns

There is a major update in functionality though – support for BLOB columns, which was requested to help store byte arrays – or Images – directly in the database.

You can define a table in the database with a BLOB column using code similar to this:

// Get a reference to the SQLite database
db = new SQLiteWinRT.Database(ApplicationData.Current.LocalFolder, "sqliteblobdemo.db");

await db.OpenAsync();

string sql = @"
    CREATE TABLE IF NOT EXISTS
        Pictures(Id     INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
                 Name   VARCHAR(140),
                 Image  BLOB);";
await db.ExecuteStatementAsync(sql);

Then, to store a record in this table, you could do something like:

private async void Insert_RecordAsync(string description, BitmapImage image)
{
    string sql = @"INSERT INTO Pictures (Name, Image) VALUES (@name, @image)";
    var db = await App.GetDatabaseAsync();
    using (var statement = await db.PrepareStatementAsync(sql))
    {
        // Convert BitmapImage to byte array
        byte[] imagebytes = ConvertToBytes(image);
        // .. and from that to an IBuffer
        Windows.Storage.Streams.IBuffer imagebuffer = imagebytes.AsBuffer();

        // set the statement parameters
        statement.BindTextParameterWithName("@name", description);
        statement.BindBlobParameterWithName("@image", imagebuffer);

        await statement.StepAsync();
    }
}

private byte[] ConvertToBytes(BitmapImage bitmapImage)
{
    byte[] data = null;
    using (MemoryStream stream = new MemoryStream())
    {
        WriteableBitmap wBitmap = new WriteableBitmap(bitmapImage);
        wBitmap.SaveJpeg(stream, wBitmap.PixelWidth, wBitmap.PixelHeight, 0, 100);
        stream.Seek(0, SeekOrigin.Begin);
        data = stream.GetBuffer();
    }

    return data;
}

Here’s an example to read data out again:

    protected override PictureViewModel CreateItem(SQLiteWinRT.Statement statement)
    {
      // Read the image from the BLOB column
        Windows.Storage.Streams.IBuffer blobBuffer = null;
        if (statement.GetColumnType(2) != ColumnType.Null)
        {
            blobBuffer = statement.GetBlobAt(2);
        }

        // Convert IBuffer back to a BitmapImage
        byte[] pictureBytes = blobBuffer.ToArray();

        var bitmapSource = new BitmapImage();

        using (MemoryStream ms = new MemoryStream(pictureBytes))
        {
            bitmapSource.CreateOptions = BitmapCreateOptions.None;
            ms.Seek(0, SeekOrigin.Begin);
            bitmapSource.SetSource(ms);
        };

      var c = new PictureViewModel(
        statement.GetIntAt(0),
        statement.GetTextAt(1),
        bitmapSource);

      return c;
    }

Here’s a complete sample app you can study to help implement this functionality in your own apps:

Sample code SQLiteBlobSample.zip

Push Notifications made easy: Using Windows Azure Notification Hubs with Windows Phone

When I built the Windows Phone 8 Jump Start training, one of the sessions was on Push Notifications. The demo app I used was an update of an old favourite, a Weather app which first saw the light of day a few years ago with the initial demos built for Windows Phone 7.0. In the demo, you have a phone app and there is also a WPF desktop app.

The WPF desktop app allows the ‘operator’ to select a city, temperature and weather conditions and then generate tile, toast and raw notification messages to communicate the weather forecast to the phone, but the WPF app is actually more complex than that and actually fulfils two key roles in a push notifications scenario, as it also hosts a WCF service and maintains a list of subscribers, simulating the cloud service that you would build for a real Push Notifications solution.

PushBasics

In summary, the phone registers for push notifications1 and receives a unique URI (the channel URI) which it then sends off to your cloud service2 (the WCF service) and the cloud service maintains a list of all subscribers for this app. Then the backend logic (the WPF UI in this demo) reads the list of subscriber channel URIs when it has something to communicate to the phone and sends the tile/toast/raw payloads to the subscriber URIs3. The subscriber URIs are actually endpoints hosted on MPNS (Microsoft Push Notification Services), so MPNS actually takes care of delivering the payloads to the phone4.

Fine – except that sample is difficult to setup and run, since you have to run Visual Studio as administrator otherwise the WCF self-hosting doesn’t work, you have to open port 8000 in your firewall because that is the port the WCF service listens on, and you have to edit the phone app code to set the correct hostname of the PC where the WCF service is running. Those are all implementation difficulties, but the real crime of this demo is that it’s too simplistic a demo and gives the impression that writing a Push Notifications solution is easier than it really is. In a real world app, when you post to MPNS you get back a response that gives you information about the state of the phone app subscription. There’s a whole page in the documentation about what you might get back: Push Notification Service response codes for Windows Phone and even if you ignore most of that, at the very least you should be removing subscribers from your list if you get a 404 Not Found response back, indicating that the subscription channel URI you posted to is no longer valid.

In fact, writing backend logic to send push notifications and correctly react to the Push Notification Service response codes is hard. And if you want to send push notifications to more than one client platform, such as Windows 8, iOS and Android, it’s incredibly hard.

That is – unless you use Windows Azure Notification Hubs Smile

Windows Azure Notification Hubs

Windows Azure Notification Hubs is a service running in Windows Azure that makes it really easy to send push notifications to mobile clients. You can read an overview here, but in essence what it does is remove the need to manage the subscriber list and create your own subscription WCF service from your backend logic and provide an easy to program API for sending notifications – and not only to Windows Phone, but to Windows 8, iOS and Android clients too.

But the benefits of Notification Hubs are not only for those building a cross-platform solution. Even if you are building a push notifications app for a single type of client, using this technology will greatly ease the creation of your solution.

I thought it would be interesting to do a new version of the Weather sample, but using Windows Azure Notification Hubs to make a comparison between the two ways of doing it, so for the rest of this post, I will walk you through what I did (download the sample code from the link at the bottom of this post).

From an architectural point of view, the main thing is that the custom WCF service and subscriber list disappears completely. Great, no need to build and host a custom web service in order to build a push solution! Instead, the notification hub fulfils that purpose and acts as a gateway between your backend logic and MPNS.

PushNotificationsWithWANH

Configuring the Notification Hub

First stage in building this is to configure the notification hub in Windows Azure, which is all done using the portal. You need to have a Windows Azure account and then go to the portal at http://manage.windowsazure.com.

  1. Click +NEW at the bottom of the screen.
  2. Click App Services, then Service Bus, then Notification Hub, then Quick Create.
  3. Type a name for your notification hub – I chose weathernotificationhub, select your desired region – West Europe for me, then click Create a new Notification Hub.
    WANHcreate
  4. You will now see the Service Bus namespace created screen.
    NotificationHubCreated

    Now, before you leave this screen, click on the Install the Windows Azure SDK (includes Service Bus client libraries) link to make sure you’ve got the client libraries installed in Visual Studio that you will need in both the phone app and also the desktop app.

  5. Click Connection Information at the bottom. Take note of the two connection strings – you will need them in a moment.
    AccessConnectionInformation

That’s it. Your Windows Azure Notification Hub is configured and ready to go.

Connecting the Phone App to Windows Azure Notification Hubs

Now let’s turn to the phone app. There aren’t many changes we need to make from the phone app we used in pre-notification hubs days. It still needs to register for push notifications using Microsoft.Phone.Notifications.HttpNotificationChannel and register for toast, tile and/or raw notifications. And when the app opens the channel, it will get a new Channel Uri reported to it when the ChannelUriUpdated event fires.

In the original app, it was at this point that you sent the channel Uri off to the WCF service hosted in the Weather Service desktop app, but instead we now send that off to our Windows Azure Notification Hub. To do this, you need to add a reference to the client libraries using the WindowsAzure.Messaging.Managed NuGet package.

In the Visual Studio menu, click Tools, then Library Package Manager, then Package Manager Console. Then, in the console window type:

Install-Package WindowsAzure.Messaging.Managed

and press Enter.

Now in the phone app, in MainPage.xaml.cs, we add the using Microsoft.WindowsAzure.Messaging using statement at the top, and then modify the ChennelUriUpdated event handler as follows:

async void httpChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
{
    Trace("Channel opened. Got Uri:n" + httpChannel.ChannelUri.ToString());
    Dispatcher.BeginInvoke(() => SaveChannelInfo());

    Trace("Subscribing to channel events");
    await SubscribeToServiceAsync();
    SubscribeToNotifications();

    Dispatcher.BeginInvoke(() => UpdateStatus("Channel created successfully"));
}

The SubscribeToServiceAsync() method is a new version of SubscribeToService() in the original demo. Instead of calling the WCF service (the commented out code), it now instantiates a Microsoft.WindowsAzure.Messaging.NotificationHub instance, which takes two arguments: the name of my notification hub (weathernotificationhub) and the connection string called DefaultListenSharedAccessSignature that you get from the Connection Strings display in the portal (step 5 in the previous section).

private async Task SubscribeToServiceAsync()
{
    try
    {
        var hub = new NotificationHub(
            "weathernotificationhub",
            "Endpoint=sb://weathernotificationhub-ns.servicebus.windows.net...[your value] ...");

        Registration registration = 
            await hub.RegisterNativeAsync(httpChannel.ChannelUri.ToString());
        Trace("Registered with Azure Notification Hub, Registration Id:" 
            + registration.RegistrationId);

        Dispatcher.BeginInvoke(() => 
            UpdateStatus("Registered with Windows Azure Notification Hub"));
    }
    catch (RegistrationAuthorizationException rEx)
    {
        Trace(rEx.Message);
        throw;
    }
}

That’s it as far as the phone client goes. Everything else stays the same: push notifications are delivered by the notifications infrastructure and handled in exactly the same way. Windows Azure Notification Hubs simply replaces your own subscription service, as far as the phone client goes.

Sending Notifications From Your Backend Logic

This is where the true benefit of Windows Azure Notification Hubs shines through. You no longer have to create your own web service with table storage to receive the channel URIs from your phone client subscribers, nor do you have to write logic to examine the status returns you get back from MPNS when you post notification messages and prune out stale registrations from the subscriber lists. You don’t need to write logic to post to each subscriber channel URI individually, just one call to the notification hub will cause the message to be sent out to all your clients. And if your backend logic needs to support Windows 8, iOS or Android clients as well as Windows Phone, the benefits of  Windows Azure Notification Hubs multiplies a hundred-fold.

Getting Registration Details from the Hub

In the Weather app, I started by deleting everything to do with the WCF registration service that we used in the previous version. Then fixed up the UI where it used to display things like “Waiting for connection…”. One thing the original did, was show the current count of registrations to the registration service. To do the same with Notification Hubs, you can call the NotificationHubClient.GetAllRegistrationsAsync(int32 top) method which returns details of all registrations limited to the top ‘n’ by the value you pass in the argument. In order to use the NotificationHubClient object, you need to add a reference to the client libraries using the WindowsAzure.Messaging.Managed NuGet package just the same as we did with the phone app.

After adding the NuGet package to my sample app, we show the number of clients on the screen using the following method:

private async Task UpdateRegistrationsCountAsync() { NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString( "Endpoint=sb://weathernotificationhub-ns.servicebus.windows.net/;…", "weathernotificationhub"); var registrationsCount = await hub.GetAllRegistrationsAsync(Int32.MaxValue);

await Dispatcher.BeginInvoke((Action)(() =>
{ txtRegistrationsCount.Text = registrationsCount.Count().ToString(); })
);
}

The NotificationHubClient constructor takes two arguments: the first is the connection string you get from the Notification Hub Connection Strings page in the Windows Azure portal, but unlike the phone client which used the DefaultListenSharedAccessSignature, this time you need the DefaultFullSharedAccessSignature as this app is doing full interaction with the notification hub, such as posting notifications. The second arg is the name of your notification hub.

Sending Toast and Tile Push Notifications

Now to the main purpose of the app. Most of the logic around formatting and sending notification messages is encapsulated into the NotificationSenderUtility class in my sample. For example, this contains the following method to format the XML to send for a Windows Phone Toast notification:

private static string prepareToastPayload(string text1, string text2)
{
    // Create encoding manually in order to prevent
    // creation of leading BOM (Byte Order Mark) xFEFF at start
    // of string created from the XML
    Encoding Utf8 = new UTF8Encoding(false); // Prevents creation of BOM
    MemoryStream stream = new MemoryStream();
    XmlWriterSettings settings = new XmlWriterSettings() 
                { 
                    Indent = false,
                //   Encoding = Encoding.UTF8    !!NO-> adds Unicode BOM to start
                    Encoding = Utf8,    // Use manually created UTF8 encoding
                };
    XmlWriter writer = XmlWriter.Create(stream, settings);
    writer.WriteStartDocument();
    writer.WriteStartElement("wp", "Notification", "WPNotification");
    writer.WriteStartElement("wp", "Toast", "WPNotification");
    writer.WriteStartElement("wp", "Text1", "WPNotification");
    writer.WriteValue(text1);
    writer.WriteEndElement();
    writer.WriteStartElement("wp", "Text2", "WPNotification");
    writer.WriteValue(text2);
    writer.WriteEndElement();
    writer.WriteEndElement();
    writer.WriteEndDocument();
    writer.Close();

    return  Encoding.UTF8.GetString(stream.ToArray());
}

WARNING: While building this, I discovered that Windows Azure Notification Hubs are quite a bit fussier about the XML you send it than MPNS actually is. The original version of the code used the standard Encoding.UTF8 in the XmlWriterSettings (commented out in the code above) which results in an invisible Byte Order Mark (BOM) character being inserted at the front of the string, which causes Windows Azure Notification Hubs to barf when you send it that. The code above creates the XML without the BOM at the front which works fine. To read more about this, see my blog post BOMbin’ the L (aka Wierd Errors with XmlWriter).

Having prepared the payload, to send a Toast or Tile is simply a case of calling the NotificationHubClient.SendMpnsNativeNotificationAsync(string payload) method. The implementation in the attached sample is slightly more complex than this, but essentially it’s the following:

    NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString(
        "Endpoint=sb://weathernotificationhub-ns.servicebus.windows.net/;...",
        "weathernotificationhub");

    NotificationOutcome outcome = await hub.SendMpnsNativeNotificationAsync(payload);

Sending Raw Notifications

The other thing the original sample does is send raw notifications directly to the app (if it happens to be running of course). The body of a raw payload is entirely up to the app developer, since unlike toast and tile notifications that may be processed by the Push Notifications handler in the phone OS, raw notifications are only ever handled by the app. So in the new version of this sample, the code building the raw notification payload is almost the same as before:

private static string prepareRAWPayload(string location, string temperature, string weatherType)
{
    // Create encoding manually in order to prevent
    // creation of leading BOM (Byte Order Mark) xFEFF at start
    // of string created from the XML
    Encoding Utf8 = new UTF8Encoding(false); // Prevents creation of BOM
    MemoryStream stream = new MemoryStream();
    XmlWriterSettings settings = new XmlWriterSettings()
    {
        Indent = false,
        //   Encoding = Encoding.UTF8    !!NO-> adds Unicode BOM to start
        Encoding = Utf8,    // Use manually created UTF8 encoding
    };
    XmlWriter writer = XmlTextWriter.Create(stream, settings);

    writer.WriteStartDocument();
    writer.WriteStartElement("WeatherUpdate");

    writer.WriteStartElement("Location");
    writer.WriteValue(location);
    writer.WriteEndElement();

    writer.WriteStartElement("Temperature");
    writer.WriteValue(temperature);
    writer.WriteEndElement();

    writer.WriteStartElement("WeatherType");
    writer.WriteValue(weatherType);
    writer.WriteEndElement();

    writer.WriteStartElement("LastUpdated");
    writer.WriteValue(DateTime.Now.ToString());
    writer.WriteEndElement();

    writer.WriteEndElement();
    writer.WriteEndDocument();
    writer.Close();

    return Encoding.UTF8.GetString(stream.ToArray());
}

I then had to do a bit of digging to figure out how to send this raw notification via Windows Azure Notification Hubs. One of the many methods of NotificationHubClient is SendNotificationAsync(Notification notification) which is a more generic Send* method than SendMpnsNativeNotificationAsync that we used before. It has the advantage that we can add HTTP headers to the request we send to MPNS, so we can define the X-NOTIFICATION header that a raw notification requires:

        // For raw notifications, have to use the more generic SendNotificationAsync() method
        Notification notification = new MpnsNotification(payload);
        notification.Headers.Add("X-NotificationClass", "3"); // Required header for RAW
        outcome = await hub.SendNotificationAsync(notification);

push end

Summary

Hopefully this has given you an introduction to building a push notification solution using Windows Azure Notification Hubs. There is plenty more to discover as I have only scratched the surface. For example, this sample sends notifications to all subscribers, but you can send to only a subset of subscribers using Tags. And of course, you can also send to Windows 8, iOS and Android clients, formatting the payloads for each client family yourself and then calling the SendWNSNativeNotificationAsync, SendAPSNativeNotificationAsync or SendGCMNativeNotificationAsync methods. An even easier way to do this, is to use the Templates feature, which is a neat way of sending a single generic message from your backend logic and allowing Windows Azure Notification Hubs to format the native message payload for each platform for you.

Here are some useful resources to allow you to dig deeper into Windows Azure Notification Hubs:

You should also be aware that Windows Azure Mobile Services uses Notification Hubs to send push notifications.

You can download the sample code described here yourself using the link at the bottom of this post. You will have to create your own notification hub and plug in your own hub name and connection strings, both in MainPage.xaml.cs in the phone project, and in MainWindows.xaml.cs in the desktop app – you should be able to find where easily enough.