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) .
Context
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.
Acknowledgement
Version 1
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.
Version 2, with TPL – ContinueWith
The code below is also functional. We receive the exception and we can manage it.
Version 3 – TPL Wait & Result
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.
Version 4 – TPL Explicit exception
This version allow us to catch the exception on the Wait() call. This code is functional.
Conclusion
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)
Update
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 🙂