244 Comments

imageHere’s a new run of the ASP.NET Web Api vs Node.js benchmark but this time with few changes:

  • ASP.NET Web Api: The release candidate is used instead of beta.
  • ASP.NET Web Api: Self-Host is used instead of IIS.
  • ASP.NET Web Api: Use of async / await
  • Node.js: Version 0.6.19 is used instead of 0.6.17.

Also the test environment was tweaked a little and this time there was a dedicated c1.medium server for the ab.

The test

A simple server which accepts a POST-request and then responds back with the request’s body.

Node.js Implementation

var express = require('express') 
    , app = express.createServer(); 

app.use(express.bodyParser()); 

app.post('/', function(req, res){ 
    res.send(req.body); 
}); 

app.listen(8080);

ASP.NET Web Api implementation

public class ValuesAsyncController : ApiController 
{ 
    public async Task<string> Post() 
    { 
        return await this.ControllerContext.Request.Content.ReadAsStringAsync(); 
    } 
}

The benchmark

I used Apache’s ab tool to test the performance of the platforms. The benchmark was run with the following settings:

  • Total number of requests: 100 000
  • Concurrency: 80

The benchmark (test.dat) contained a simple JSON, taken from Wikipedia.

{
     "firstName": "John",
     "lastName" : "Smith",
     "age"      : 25,
     "address"  :
     {
         "streetAddress": "21 2nd Street",
         "city"         : "New York",
         "state"        : "NY",
         "postalCode"   : "10021"
     },
     "phoneNumber":
     [
         {
           "type"  : "home",
           "number": "212 555-1234"
         },
         {
           "type"  : "fax",
           "number": "646 555-4567"
         }
     ]
 }

Here’s the whole command which was used to run the performance test:

ab -n 100000 -c 80 -p .test.dat -T 'application/json; charset=utf-8' http://localhost/

The performance test was run 3 times and the best result for each platform was selected. The performance difference between the test runs was minimal.

The Test Environment

The benchmark was run on a Windows Server 2008 R2, hosted on an c1.medium Amazon EC2 –instance:

image

Specs of the instance
  • 1.7GB memory
  • 5 EC2 Compute Units (2 virtual cores)
Versions
  • Node.js: 0.6.19
  • ASP.NET Web Api: The release candidate.

The ab has its own dedicated c1.medium –instance. All the instances were on the eu-west-1a zone and the private IP was used to connect the ab and test servers.

The Benchmark Results

image

Web ApiNode.js
Time taken (in s)59,6454,73
Requests per second1676,761827,33
Time per request (in ms)47,7143,78
Failed requests00

Few words about the multi-core systems

Where Node.js is limited to a single thread and as such only uses one processor core, self-hosted Web Api can automatically take advantage of multi-core systems. With Node.js you have to use for example cluster in order to split the workload between the cores.

Here’s a graph from ASP.NET Web Api-server which shows the CPU usage of each logical processor (from my local machine):

image

Here’s an overall CPU usage when running the Node-server:

image

And here’s the same graph but this time with the ASP.NET Web Api-server:

image

The Code

The source code for the implementations and also the test tools (ab.exe, test.dat) are available from GitHub.

8 Comments
  •   Posted in: 
  • UWP

imageOne small tip if you’re creating a Windows 8 Metro app and want to update the live tile periodically using the TileUpdater-class: The request made by the OS for the live tile update doesn’t set the Content-Type so make sure that you backend is actually returning XML by default.

I encountered this when I built my app’s backend using ASP.NET Web Api and noticed that the live tile updates weren’t actually working. The backend was returning JSON instead of the XML because that’s the default format for the Web Api. In my case the backend only serves the live tile updates so I completely removed the JSON-formatter:

var config = new HttpSelfHostConfiguration("http://localhost:8080");

config.Routes.MapHttpRoute("Default", "api/{controller}/{id}", 
    new { id = RouteParameter.Optional });

config.Formatters.RemoveAt(0);

using (var server = new HttpSelfHostServer(config)) 
{ 
    server.OpenAsync().Wait();

    Console.WriteLine("Press Enter to quit."); 
    Console.ReadLine(); 
}

Now the backend is returning XML and the periodic live tile updates work properly.

3 Comments
  •   Posted in: 
  • UWP

imageThe Windows Phone OS has a global Theme setting available for the user to change. This one setting affects every application. The Windows 8 seems to take a different approach (at least in Windows 8 RP): There’s no global theme setting, instead it’s up to the developer to decide if her application uses the dark or the light theme.

Defining the application theme in XAML

Maybe the easies way to define the application theme for the Metro application is to use the App.xaml. The Application-element has a RequestedTheme-attribute which can be set to either Dark or Light.

<Application 
    x:Class="windows8_metro_themes.App" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:windows8_metro_themes" 
    xmlns:localData="using:windows8_metro_themes.Data" 
    RequestedTheme="Dark">

The App.xaml route works well if the theme is hard coded. But if the user can customize app’s theme, it’s maybe easier to set the theme in code.

Defining the application theme in code

The application theme can be set in the constructor of the App-class using code.

RequestedTheme = ApplicationTheme.Light;

The application theme cannot be changed when the application is running and trying to set it throws an exception. For example the OnLaunched-method in App.xaml.cs is already too late.

You could read the theme from application’s settings, making the theme configurable. Here’s an example where the current theme is stored in to application’s roaming settings:

var settings = Windows.Storage.ApplicationData.Current.RoamingSettings;

string currentTheme = null; 
if (settings.Values.ContainsKey("currentTheme")) 
{ 
    currentTheme = settings.Values["currentTheme"] as string; 
    settings.Values.Remove("currentTheme"); 
}

settings.Values.Add("currentTheme", currentTheme == "light" ? "dark" : "light");

And here’s App’s constructor where values is read:

public App() 
{ 
    this.InitializeComponent(); 
    this.Suspending += OnSuspending;

    var settings = Windows.Storage.ApplicationData.Current.RoamingSettings;

    if (settings.Values.ContainsKey("currentTheme") && (string) settings.Values["currentTheme"] == "light") 
        RequestedTheme = ApplicationTheme.Light; 
    else 
        RequestedTheme = ApplicationTheme.Dark; 
}

Note that the RequestedTheme-attribute in App.xaml seems to override the value set in the App’s constructor.

Defining the application theme for the Visual Studio designer

It’s possible to test both of the themes without running the app, using the Device-dialog.

image

You can switch between the Dark and the Light theme easily. The same dialog has other interesting options too, like the ability to switch the device inside the designer to the portrait mode.

Theme definitions

The XAML of the different themes are available from the following location: C:Program Files (x86)Windows Kits8.0Includewinrtxamldesignthemeresources.xaml

Links

5 Comments
  •   Posted in: 
  • UWP

The Release Preview of Windows 8 broke some things but fortunately there’s a quite good migration guide available which highlight most of the changes (Word document):

Migrating your Windows 8 Consumer Preview app to Windows 8 Release Preview

Unfortunately the guide seems to have missed some changes, like the removing of CoreDispatcher.Invoke and BeginInvoke –methods.

Breaking Change between Consumer Preview and Release Preview:

The following code worked in WinRT app with Consumer Preview:

dispatcher.Invoke(CoreDispatcherPriority.Normal, (s, e) => action(), dispatcher, null);

But the Invoke-method is now gone. If it’s OK that the action is executed asynchronously in UI thread (like BeginInvoke), this seems to be the way to go in Release Preview + WinRT combination:

dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => action());

But if the invoke must happen synchronously (like Invoke), async / await can be used:

await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => action());

UIDispatcher - A helper class which allows the synchronous and asynchronous execution of methods in UI thread:

Here’s a complete UIDispatcher-class which can be used to execute actions in UI thread:

using System;
using System.Threading.Tasks;
using Windows.UI.Core;
using Windows.UI.Xaml;

namespace Helpers
{
    public static class UIDispatcher
    {
        private static CoreDispatcher dispatcher;

        public static void Initialize()
        {
            dispatcher = Window.Current.Dispatcher;
        }

        public static void BeginExecute(Action action)
        {
            if (dispatcher.HasThreadAccess)
                action();

            else dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => action());
        }

        public static void Execute(Action action)
        {
            InnerExecute(action).Wait();
        }

        private static async Task InnerExecute(Action action)
        {
            if (dispatcher.HasThreadAccess)
                action();

            else await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => action());
        }
    }
}

Initialization:

Call the Initialize-method at the application startup, for example in App.xaml.cs's OnLaunched-method:

// Place the frame in the current Window and ensure that it is active
            Window.Current.Content = rootFrame;
            Window.Current.Activate();

            UIDispatcher.Initialize();

Without this the UIDispatcher won't work.

Invoking actions on UI thread:

After the UIDispatcher has been initialized, the Execute-method can be used to invoke actions in UI thread synchronously and BeginExecute to invoke action asynchronously:

ThreadPool.RunAsync(operation => UIDispatcher.Execute(() => this.Test.Text = "hello!"));

Links:

Here’s a good explanation by Jon Skeet about the differences of BeginInvoke and Invoke.

1 Comments

AdafyAdafy Oy is a software startup with a focus on building apps for Windows Platforms. We build andhelp you to build apps for Windows Platforms:

  • Windows 8
  • Windows Phone
  • Windows Azure

We offer development services and consulting and we’re available for hire.

Windows 8

Our first Windows 8 app participated in and passed the Microsoft Quality Labs and it’s set to launch into Windows Marketplace in near future. We do internal Windows 8 app development and also offer Windows 8 development services and consulting.

Windows Phone

We have a popular portfolio of our own Windows Phone apps like IRC7, Ampparit.com Reader and SuomiFutis. We also offer Windows Phone application development services and consulting.

Windows Azure

We use Windows Azure platform to run our ASP.NET MVC and Node.js back-ends. We’re currently in the middle of building a Azure based cloud service for Windows application developers. If you’re thinking of moving your existing web app into the Azure or if you’re starting a green field Azure project, we can help you.

More details:

Adafy is a:

And like previously mentioned, we’re available for hire.