Silverlight 5 and Tasks : strange behavior ! (Updated)
This blog post aims to talk about a strange behavior of Silverlight when using TPL (Tasks parallel library) .
You may need to integrate OData service in Silverlight. In this context, you could add your business code in the Silverlight part. It can result a sequence of asynchronous call in Silverlight (like Russian doll) :
When server raises an exception it must be propagated to the client (with or without message).
In my future example, I will try to create an address in AdventureWorks database, without filing mandatory fields, and asynchronously save it. The save MUST raise an exception. I will describe all methods used to do this.
The first version is fully functional and raises an exception in the callback. In a single call, we can’t see the difference but, in multiple and sequenced call, the process can be heavy.
Thanks to task parallel library, a new call system can be developed with Silverlight 5, based on Task.
The code below is also functional. We receive the exception and we can manage it.
With or without the t.Wait(), t.Result must wait and block thread until result arrives. But this code is not functional. The test is a success without exception but it blocks when server raises an exception. I have done the same test in WPF (same server, same service, OData reference generated asynchronously) and WPF does not have this strange behavior.
This version allow us to catch the exception on the Wait() call. This code is functional.
This peaces of code show us that a service exception is not caught/raised properly by Silverlight if you use Wait() or Result() without ContinueWith instruction…
Have you already experienced this strange behavior?
PS : Here is the source code for my tests : SilverlightApplicationTPL.zip (you may need AdventureWorks database and a local IIS)
One of my collegues ask me to check some points for the working and the non-working scenario :
OData request : The OData request is perfectly send is both cases. Here is the fiddle traces :
In debug mode, it is clear that ContinueWith version will raise an exception …
… and t.Result version has not any exception before calling t.Result and before program hangs :
Output window : in both cases, we see that the version 2 perfectly raises exceptions :
But version 3 does not :
There is still no response 🙂