Async singleton initialization

Still in these days you once in a while have use for a singleton object. But how do you achieve a thread-safe singleton that requires async initialization?

First, let’s start off with a good ol’ singleton class that can be constructed synchronously.

Synchronous Singleton

Assuming your singleton class needs some initialization data that it can construct itself (synchronously). To make it thread-safe, we rely on locking on a static read-only object.

In the version above the Singleton property is designed to work as quick as possible, only entering the lock if there is a chance that the class hasn’t yet been initialized. Within the lock, a method that creates the MySingleton object is called. This way it’s ensured that only one instance of the MySingleton is ever created.

Asynchronous Singleton

But what to do if the CreateSomeData method would work asynchronous, returning a Task<SomeData> instead, using the await keyword? Let’s modify the code in this way:

Making this change, we should play nice and propagate the async’ness to the CreateSingleton method:

That would naturally imply that the Singleton property should also be asynchronous, returning a Task<MySingleton> instead.

So, is that possibly?

First of all, it turns out that it’s not allowed to use the async keyword with a property. But this is no biggie, we could afford a method instead.

But more importantly, we are not allowed to use a lock around an await keyword. (This is actually a good thing, since the lock would really work against us here – so we should thank the C# team for not allowing this!)

So how do we do this then? As a starter, a naïve, non thread-safe solution would look like this:

Requesting the Singleton property would of course lead to a call to the CreateSingleton method every time, and would hardly be a singleton…

But the solution to make it both a singleton and thread-safe turns out to be ridiculously simple – we let the inner mechanisms of the Task class work for us!

So, how does a task work?

Let’s say you have an instance of a Task<T> and you await it once. Now the task is executed, and a value of T is produced and returned to you. Now what if you await the same task instance again? In this case the task just returns the previously produced value immediately in a completely synchronous manner.

And what if you await the same task instance simultaneously from multiple threads (where you would normally get a race condition)? Well, the first one (since there will be one that gets there first) will execute the task code while the others will wait for the result to be processed. Then when the result has been produced, all the await’s will finish (virtually) simultaneously and return the value.

So, a Task is thread-safe, and it looks as if we could use this power in our advantage here!

In the end, all we need is to replace the old Singleton property with this one:

Or, rewritten in a more classic C# way (without making use of the fancy new C# 6 “read-only properties” and “property initializers”):

So the dead simple solution is to assign the async method to a read-only (static) Task field (or read-only property in C# 6). This gives you both a singleton and thread-safety for free!

Lazy Synchronous Singleton

Being empowered with the super-simple async version, you might wonder if there really is no similar way to achieve this in the synchronous version?

Of course there is!

Revisiting the synchronous first version of the MySingleton in this blog post, you may replace the SyncObj and _singleton fields and the Singleton property with these two lines:

Or, if you prefer the pre-C# 6 code:

Wow, magic! No need for locks or anything! So how does this work?

Well, the Lazy<T> can be seen as the synchronous counterpart to the Task<T> in some aspects. At least it has the same singleton and thread-safety properties, and keeps its results for latecomers.

As you can see, the constructor of the Lazy<MySingleton> is given the means of producing a MySingleton (i.e. the CreateSingleton method) – not an instance of the type directly. Then, when someone is requesting the Singleton property, the Value of the Lazy-class is accessed. And in the same manner as the Task, the first one reaching for the Value will make the actual call to the CreateSingleton method. Any other thread asking at the same time will simply be hanging in the Value getter, and continues once the CreateSingleton method is done and the Value is produced. Further on, any consecutive calls to the Value getter will return immediately with the same instance of the MySingleton. So, again, the Lazy gives us both a singleton and thread-safety.

And there was much rejoicing!

Best practices of the Dictionary class

It’s important to know how the standard classes behave so that your code gets optimized, not performing unnecessary checks or making unnecessary calls.

Here are a number of issues I’ve seen time after time:

Fetching a value from the dictionary only if it exists

In the first version (bad) there are two dictionary lookups performed. It’s like walk in to a public library asking the librarian whether a certain book is in – and when the librarian comes back and says “yes, it’s in”, you ask again saying “Good, could you please get it for me?”. In real life it’s pretty obvious that this is a silly behavior, but in the computer world it’s not that apparent.

  🙁
In the second version (good), only one lookup is performed:
  🙂

Accessing all the keys and values

I’ve seen many real-life cases where access to both the key and value is needed in a foreach-loop, and the iteration is performed over the Keys-properties while the value is accessed by a lookup:
  🙁
If you want both the key and the value simultaneously it’s better to iterate over the dictionary as KeyValuePairs:
  🙂
(Obviously; if you want only the keys you should use the Keys-property, and if you want only the values use the Values-property)

Overwriting a value

  🙁
There is really no need to remove a key before assigning a new value to it:
  🙂

Removing a value

Once again, the following implementation leads to two lookups:
  🙁
The Remove-method is actually very kind. It doesn’t crash if you try to remove something that is not there but returns a bool telling the result of the operation:
  🙂

When may my call fail?

The call… …fails when
Never (*)
The value will be added if it’s not already in the dictionary, and it will be replaced if it does.
 
When the entry “key” does not exist.
 
When the entry “key” already exists.
 
Never (*)
 
Never (*)
(And the call returns false if the entry “key” does not exist.)
(*) Well, you get an ArgumentNullException if the key is null…

Follow the rules when developing your Windows Phone app

Roughly one month after the first version of Badgers Rock had passed the certification cycle and happily thrived in the Windows Phone Marketplace, I received the following e-mail from one of the app testers: 

Dear Windows Phone Marketplace Developer,

It has been determined through certification testing that the application indicated in the subject line has the following problem(s):

5.2.4.4
Pass with Notes: Pressing the device back button has no effect on the application.

Steps to Reproduce:
1. Launch the application.
2. Select “PLAY!”.
3. Select a stage.
4. Press the device Back button.
5. A pause menu is displayed.
6. Press the device Back button again.
7. Observe the application the application does not respond.

The application passes certification, however the reported issues need to be resolved in the next update to the application.

ACTIONS REQUIRED: Please address the issues listed above, review the Windows Phone Application Certification requirements (http://go.microsoft.com/?linkid=9730556) and resubmit your updated application for certification testing.  Future application update submissions will fail certification testing if the same issue(s) are not corrected.
P
LEASE DO NOT REPLY TO THIS MESSAGE. For further assistance, please visit Developing for Windows Phone 7 forum.

Thanks,

Sam
Windows Phone Marketplace Certification

Sam was absolutely right about his finding, but it was in fact a design decision from my side. In the described scenario you are in an ongoing game and then you press the physical Back button on the phone. The game is now paused and you are presented with a couple of options; basically “do you want to end the game or resume?”. So, at this point, how should I handle the Back-button? It was of course out of the question to end the game; it’s way too simple to accidentally touch this button (depending on how you are holding the device). So making a double miss-tap ending the game would not make any hardcore Badgers Rock-gamer happy. So should the game resume then? This was the only obvious option left (making the game respond to the click), but I didn’t really like that anyway because it would not be 100% clear to the player what the Back button would actually do in this case. So I decided to ignore the Back button in this screen and force the player to take an active decision choosing from the spelled-out options on screen — again, to make it perfectly clear for the player what will happen.

Then this message came from which a couple of things can be noticed:

  • First of all, Microsoft is (for the first time?) really anxious that all the applications are behaving in a consistent way, not only giving guidelines. This is a good thing.
     
  • Secondly, it’s not only automatic testing being performed on your submitted app. This is also a good thing. Although it doesn’t seem as every release is tested manually since I had maybe four versions successfully passing the certification cycle when I got this message — and the behavior in question had been there from the start.
     
  • Also, at the point in time when I received this message there was no certification phase currently going on; my latest release had already been passed successfully some time ago. Does this mean that the testers are doing the manual testing as a parallel task on top of the (more or less) automatic certification cycle? My app was presumably put in a queue and rested there for a month until someone (Sam!) had time to perform the manual testing.
     
  • A side note is the not-so-professional link they’ve included in the e-mail (http://go.microsoft.com/?linkid=9730556). This points to a PDF-file you’ll have to download that’s only telling you that the link has been moved (and of course where to). Suprising? Not really. Elegant? Well, not really…

Of course I should follow the requirements of always having a responsive Back-button!
So now during game-play, the Back-button will basically toggle pause mode on and off.

Google Translator Changes Company Names

How neutral is really the Google Translator?

At least when it comes to some manufactures of integrated circuits they seems to be quite creative. Try to translate these two sentences from Swedish to English:

Jag föredrar Microchip som företag.
Jag är kritisk mot Microchip som företag.

It will be translated to…

I prefer Microchip as a company.
I am critical of Analog Devices as a company.

…which is aaalmooost a correct translation — apart from the minor detail that the company name has been replaced with one of its chief competitors!
But — worth noticing (or coincidence?) — only in one of the phrases (that happened to have a negative meaning)!

Oookkeeyyy?

Translating the same Swedish sentences to German shows the exact same phenomena:

Ich bevorzuge Microchip als Unternehmen.
Ich bin kritisch gegenüber Analog Devices als Unternehmen.

But if you then translate these two German sentences back to English you will get another weird name-switch:

I prefer Microchip as a company.
I am critical as compared to Texas businesses.

So, apart from the bad translation of the second sentence from German to English, now “Analog Devices” has been replaced with “Texas”. Should that be “Texas Instruments” perhaps? Well maybe… If you take the original two Swedish sentences and replace “Microchip” with “Micrel” (yet another manufacturer of integrated circuits):

Jag föredrar Micrel som företag.
Jag är kritisk mot Micrel som företag.

Translating this to English, now “Micrel” will magically switch to “Texas Instruments” (but now in both sentences):

I prefer Texas Instruments as a company.
I am critical of Texas Instruments as a company.

Two question remains; Who paid Google to replace the names? But the more interesting question is perhaps: What did they really try to accomplish with these mysterious switches?

Conspiracy Now!