Skip to main content
Anything related to the .NET framework

Windows Store app Development Snack: The vastness of CPU time

For more posts in this series, see the series index.

I have written in a previous post (What do you get from being a lock screen app?) about how your background processing has a limited amount of time to do it’s processing in, what the odd unit of measurement used (the CPU second) and the overflow bucket. Even with the thinking it is hard to understand what you can accomplish in the time available, so help let’s look at what an app I built (Bing my lockscreen) does in it’s time.

In short what I hope you take away from this, is that you do get a decent amount of time and that with careful planning you can do a lot!

The Process

First off, Bing my lockscreen since it uses a timer requires lock screen permissions which means it gets at least 2 CPU seconds every fifteen minutes, plus overflow from the bucket.

First thing that happens is we get a deferral object (similar to what was explained in Async & Sharing) since we need to use async in the background task. Now we go to the RoamingSettings values to get a boolean (which needs to be cast, since RoamingSettings is a Dictionary of string & object) to see if the user has disabled automatic updates. Now assuming the user hasn’t disabled automatic updates, we connect to a web site using the HttpClient & HttpClientHandler classes and pull down some JSON as a string and convert it to an object using Windows.Data.Json.JsonObject.

Aside: if I felt too tight on CPU, I may swop to the AWESOME Json.NET, which has a better parsing performance.

If all that worked (and there is minimal logging and status checks happening in here too), I use a touch of Linq to get the first image from the IEnumerable collection that it is stored in internally. I then check the URL of the image against a value stored in LocalSettings, as I do not wish to update the lock screen with the same image multiple times. If the image is different, I download the image from Bing to the TemporaryFolder, check the file size is greater than 0. If it is, then I call the SetImageFileAsync method to change the lock screen, else I delete the damage file. Downloading is far more complex than it first appears as I need to handle proxies, handle scenarios where I can’t get the 1920x1200 resolution and need to fall back to the 1366x766 resolution image, ensure everything is written to disk BEFORE the lockscreen is set (I had some issues with I/O buffers in earlier versions that caused a minor corruption on images because they were not flushed to disk!).

Aside: Important to remember that CPU seconds, is time the CPU works – when the CPU is idle say because you are doing something I/O bound like a download, it doesn’t count!

Next I store the result of this to the log, which is just a container in LocalSettings (so that means the first time this is run we create the container too!) and store the URL of the newly changed image too. Now the process continues in a similar way for the live tile! We check if the last live tile update is the same based on the URL for the image (again comparing to a value stored in LocalSettings). I then use the TileNotification and the TileUpdateManager to send the tile update. I do not need to download the tile image in this case, as tiles do support remote URL’s for the images. Lastly I update the LocalSettings for the updated tile!

Line count

If you count the lines of code executed for this, and I am excluding blank lines, namespace declarations, comments – really just the code that actually runs it is approx. 190 lines of C# code! Far more than you may think.

More stats!

I used the always amazing NDepend to generate some more stats on the assembly which does all the background processing:

  • IL instructions: 2 092
  • lines of code (LOC): 80
  • lines of comment: 9
  • Percentage Comment: 10%
  • Methods: 99
  • Fields: 75
  • Types: 18
  • Namespaces: 2
  • Assembly Level: 1
  • Abstractness: 0.11111
  • Instability: 1
  • Dist from main seq: 0.078567
  • Normalized dist from main seq: 0.11111
  • Relational cohesion: 2.3333
  • Afferent coupling (AsmCa): 0
  • Efferent coupling (AsmCe): 17

LOC is different here since NDepend uses the compiled assembly and works back, while I counted lines in Visual Studio. Same is true for methods, which NDepend works out from the compiled assembly and thus includes all anonymous methods - where if I counted that in VS, it would be 8 or 9 methods.

Up skill from VS/TFS 2010 to VS/TFS 2012

I got some great news today that Colin from Imaginet will be running a fantastic two day course at Bytes in Midrand soon (19th & 20th November). 

Attached is the pamphlet for the event – which I highly urge you to have a look at and attend!

Windows Store app Development Snack: Side loading apps for development purposes!

For more posts in this series, see the series index.

One of the things you need to think of when you are going through your development cycle is how the decision makers are going to test your app? 

Likely the best solution is to get it to their hands via a device, but how do you load your application onto that other device? Well there are TWO options!

Building the app

Before you do that however you need open your project in Visual Studio, right click on the project and go to the Store option, then client the Create App Packages option.

image

Since you are creating them for side loading you do not need to associate them with the store.

image

Once done you will have a folder (called the output location) with both a .appxupload & another folder in it – we will call this the deployment folder.

image

PowerShell

imageRegardless of the machine, if it has Windows 8 on it – it has PowerShell too so this option works FANTASTICALLY for everyone.  Step one is to load a developer license onto the machine, you can do this by typing: Show-WindowsDeveloperLicenseRegistration

You will now get the prompt for your Live ID to register the device unlocked for three months.

Next you need to ensure you can run PowerShell scripts, this is done using: Set-ExecutionPolicy unrestricted

Now copy the deployment folder to the device and using PowerShell run the Add-AppDevPackage.ps1 – This will prompt you about installing it and installing the required certificates. Say yes to those and the app will install on the device!

Visual Studio Debuggable Package Manager

If the device has has Visual Studio on it there is another option you can use which just requires the .appx package. That is the Debuggable Package Manager

image

When you launch that you can use the Add-AppxPackage command to install any appx you have. You can find the .appx file in the deployment folder.

AppXUpload

if you only have an .appxupload file – you can still use that too! Just remain it to a zip file, open it up in your favourite compression tool and extract the appx file from there!

TechDays 2012 - wrap up post

Thank you so much for those people who came to my talks in Johannesburg & Cape Town – from all accounts we broke some size records for the event which is very awesome. Not just for my ego, but also it shows Microsoft that while we are excited about the new awesome stuff – we NEED to hear about the more normal things, you know cause we get paid to work with that and all.

With that said on to the usual post event blog post where I share my slides. In addition my demo script (those masses of paper I used to remind myself what to type) is up, and finally are completed builds of the demo apps for you to look through. About the demos, two things need to be remembered:

  • These are demos – they are not meant to best practise. They are as close to that as I can get in 5min, so disclaimer on using them.
  • These demos are not the same as on stage, and have no help – so if you did not attend the session the script maybe a better starting point.

btw download the slide deck, there is hidden slides with more info!!

Completed Demos

Large (file size) demos

Small (file size) demos - below

Windows Store app Development Snack: Dealing with Async warnings

For more posts in this series, see the series index.

In this post I am going to look at a side effect you find a lot with when using the new async modifiers: compiler warnings. While this post is in my Windows Store app dev series, it applies equally well to development on .NET 4.5 with ASP.NET, WCF, WPF etc… really anywhere you use Async.

CS1998

warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Cause: You have specified the async modifier on a method, but you are not using the await keyword anywhere in the method.

This is a warning you should be investigating because it is there for one of two reasons:

  • You have async on the method, but do not need it – so remove it.
  • You have async on the method, because you need it & you forgot to use the await keyword! So time to fix up the code.

CS4014

warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

Cause: You are calling a method which has the async modifier & returns a task – yet you are not awaiting on that method call.

This maybe be showing you a place where you forgot the await keyword so very important to check these out too. However these can come up when you intentionally do not use the await keyword. For example, you have decided to call a method and you know it will run async and none of the code following it needs to work with the result.

Microsoft has a great page on this compiler warning which goes into far more detail, especially regarding Exceptions that is worth reading.

You may think the solution here is to suppress this warning:

#pragma warning disable 4014
            AwesomeAsync();
#pragma warning restore 4014

Which I think is not a bad solution, as it does show clear intent by the author of the code that they are aware of the issue and are intentionally ignoring it. However it is not a good solution either, forget to restore it or get the warning number wrong in the restore and you have unintentionally suppressed large parts of your code base.

The better solution is just to assign the result (a task) of the method to a variable:

var ᛘ = AwesomeAsync();

You may not like these extra variables lying around – but remember the compiler is pretty smart, it will remove them for you at compile time if they are not needed. The following images are firstly the code I used in one of my apps, and then the code as it was compiled to (I used the awesome Reflector to see the compiled code) and note the t variable is gone!

Clipboard01=3Clipboard01=2

Lastly you maybe wondering why I am using ᛘ as my variable name – because it is hard to type. I want to ensure that no one starts using that variable unless they have a good reason and so this odd character means that the moment you need that variable you will likely give it a good name and use it properly with thought. It also is one character so takes up minimal code space. Lastly because it is so unique it does make it easy to identify the purpose when reading code (meta data in the letters) so no comment is needed. If you have feedback on this usage, I would love to hear it in the comments below!

Windows Store app Development Snack: Debugging Share Target experiences

imageFor more posts in this series, see the series index.

The debugging experience for Windows Store apps is FANTASTIC – you have all these great tools in Visual Studio when you are running your application, but what about for scenarios where you need to debug when your app isn’t running.

For example when you are a Share Target, as the Share Source is the running application while the Share Target is launched by Windows when the user selects the target – and if you need to debug the target how do you do that?

The trick is hidden in the project settings, under the Debug section. There is an option called Do not launch, but debug my code when it starts which if you enable and then press F5, Visual Studio will jump into debug mode but not run any code. Then when Windows launches your code, say in the share target Visual Studio will attach to it automatically and enable that FANTASTIC debugging experience!

Windows Store app Development Snack: Changing the application theme from dark to light

For more posts in this series, see the series index.

imageYou may have seen in Visual Studio & Blend the option to change the Windows Theme from dark (the default) to light. The problem is that is a runtime it seems to make zero difference and there is no way in Windows 8 to change it (like we had with Windows Phone).

The solution to this is to change it in the App.xaml file – but going to the Application node (the very first one) and adding RequestedTheme="Light" to switch to the light theme or RequestedTheme="Dark" to switch to the dark theme.

image

This will have a massive impact on the overall appearance of your application!

image

A word of warning – you may also see the runtime property for this under App.Current.RequestedTheme and assume you can change it at runtime, however that will raise a NotSupportedException. What you can do is set it on start-up, so if you want to change it “dynamically” the user will need to restart the app for the change to be applied (Microsoft has a sample to show this).

image

Lastly an interesting tidbit from the documentation on this:

This property is ignored if the user is running in high contrast mode.

Windows Store app Development Snack: Feedback links in your app

imageFor more posts in this series, see the series index.

Something I have started to do with my applications is to make it easy for the people who use the applications to send feedback – since that is the best way to improve it is based on the feedback of those who use it. The question then becomes, how to I collect this feedback?

I could put some screen in the application but I decided to rather have a simpler method for this – email. All I need now is a way to launch the email program and ideally have my email address & subject prefilled – which is not possible with the share source experience.

The solution to this is something we have used for a long time before Windows 8 – protocol handlers, and in particular mailto.

So how do you launch a protocol handler in a Windows Store app – the same way you launch a web page, the Launcher.LaunchUriAsync method.

The usage of protocol handlers does open a lot of possibilities too for sharing between Windows Store apps & Windows desktop apps!

Windows Store app Development Snack: Async & Sharing

For more posts in this series, see the series index.

Here is an interesting issue, you need to implement a Share Source but to do the sharing you need it to be an async call. So what do you do? You can add the async & await modifiers but it won’t work correctly. The solution is to use the deferral which is given to you in the arguments of the event and when you are done you call the Complete method on it to indicate that you are done with all the async goodness:

async void App_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
    var deferral = args.Request.GetDeferral();

    // async code with await keyword here

    deferral.Complete();
}

Windows Store app Development Snack: What do you get from being a lock screen app?

For more posts in this series, see the series index.

When you start with development of Windows Store apps, you may want to run tasks in the background and an important aspect of that is deciding if you want to be a lock screen app or not.  Microsoft has a guide on this, which is ESSENTIAL reading so this post should be seen as a cheat sheet for a portion of that document.

Triggers

Background tasks kick off on a trigger so what triggers can lock screen & non-lock screen apps use. Non-lock screen apps can run background tasks based on

Background task trigger type

Trigger event

When the background task is triggered

MaintenanceTrigger

MaintenanceTrigger

It’s time for maintenance background tasks.

SystemEventTrigger

InternetAvailable

The Internet becomes available.

SystemEventTrigger

LockScreenApplicationAdded

An app tile is added to the lock screen.

SystemEventTrigger

LockScreenApplicationRemoved

An app tile is removed from the lock screen.

SystemEventTrigger

NetworkStateChange

A network change such as a change in cost or connectivity occurs.

SystemEventTrigger

OnlineIdConnectedStateChange

Online ID associated with the account changes.

SystemEventTrigger

ServicingComplete

The system has finished updating an application.

SystemEventTrigger

SessionDisconnected

The session is disconnected.

SystemEventTrigger

SmsReceived

A new SMS message is received by an installed mobile broadband device.

SystemEventTrigger

TimeZoneChange

The time zone changes on the device (for example, when the system adjusts the clock for daylight saving time).

Lock screen apps can use those and much more, the extra triggers for lock screen apps are

Background task trigger type

Trigger event

When the background task is triggered

ControlChannelTrigger

ControlChannelTrigger

On incoming messages on the control channel.

PushNotificationTrigger

PushNotificationTrigger

A raw notification arrives on the WNS channel.

SystemEventTrigger

ControlChannelReset

A network channel is reset.

SystemEventTrigger

SessionDisconnected

The session is disconnected.

SystemEventTrigger

UserAway

The user becomes absent.

SystemEventTrigger

UserPresent

The user becomes present.

TimeTrigger

TimeTrigger

A time event occurs.

CPU

Now we know when the background task will happen, how much CPU can background task consume during it’s execution is also affected by lock screen & non-lock screen.

Before we look at the table there is three things to know:

  • This is per app – NOT per background task!
  • Think of the refresh period as the point were we get filled up with more resources. So you can run multiple background tasks and they all consume from the pool of resources. At the refresh period the bucket is filled & any unused time will be lost.
  • CPU second is not the same as a real second. A CPU second is the amount of time that is consumed by the CPU – so if you are doing I/O (like a download) then it is not counted.

CPU resource quota

Refresh period

Lock screen app

2 CPU seconds

15 minutes

Non-lock screen app

1 CPU second

2 hours

Bandwidth

In a similar way to CPU the amount of data you can consume is also effected by being a lock screen app, but in addition to that the average speed of your internet also effects the amount of data. There is another difference to CPU, rather than one bucket – there is two:

  • Small period: The shorter amount of time and has a small amount it can be downloaded.
  • Day: The max per day – so accumulation of all the smaller ones cannot exceed this.

The table below has 1Mb & 10Mb as the average speed options but you could think of them as 1Mb = WiFi and 10Mb plugged into a network. These amounts are the top end, so if the network is slow you get less.

Average throughput Lock screen apps Non-lock screen apps
Every 15min Per day Every 2 hours Per day
1Mb/s 0.469Mb 4.69Mb 0.625Mb 7.5Mb
10Mb/s 4.69Mb 450Mb 6.25Mb 75Mb

Global Pool

Above we have looked at the resource constraints for CPU & bandwidth but what happens if that isn’t enough? Windows has a global pool of additional CPU & bandwidth resources that are shared system wide. This means that if you need 2.5CPU seconds you will likely get it! However the global pool is shared across all the apps, so it is not guaranteed (the above resources we have looked at are guaranteed). So if you have some abusive apps that use it, then your app may not get anything from the global pool. The global pool is replenished every 15min.

You can test your app works with an empty global pool, and you really should do this, by turning it off in the registry

Value name

Type

Default value

Description

HKEY_LOCAL_MACHINE\ SOFTWARE\Microsoft\Windows NT\CurrentVersion\BackgroundModel\Policy\CpuEnableGlobalPool

DWORD

1

Controls the CPU global pool. A value of zero disables CPU global pool.

HKEY_LOCAL_MACHINE\ SOFTWARE\Microsoft\Windows NT\CurrentVersion\BackgroundModel\Policy\NetEnableGlobalPool

DWORD

1

Controls the network global pool. A value of zero disables network global pool.

Control channel

Taken from Staying connected in the background.

The network trigger feature supports two possible resource types for a push notification or keep-alive network trigger:

  • Hardware slot - Allows the app to use background network notifications even in low-power or connected-standby mode.
  • Software slot - Allows the app to use background network notifications but not in low-power or connected-standby mode.

This notion of slot is integral to the network trigger and is not required for WNS.

One of the options to specify while registering for the network trigger feature is the hardware or software slot resource type. This resource type capability provides a way for your app to be triggered by an incoming notification even if the device is in low power mode. By default, a software slot is selected if the developer does not specify an option. A software slot allows your app to be triggered when the system is not in connected standby. This is the default on most computers.

On the other hand, a hardware slot allows your app to be triggered at all times including when the system is in connected standby. Only systems with network devices that support connected standby will have a hardware slot. Note that the app cannot be triggered through a software or hardware slot when the system is in Sleep or Hibernate mode, or is shut down.

An app can create and use a maximum of 5 network triggers. There is also an additional system limitation on number of network triggers that specify hardware slots. The first 3 lock screen apps that register for a hardware slot for a network trigger can use a maximum of 3 hardware slots per app. Any other lock screen apps beyond the first three apps registered for hardware slots are limited to only software slots for their network triggers.