A frequent complaint I hear from developers working on Silverlight applications for Microsoft Dynamics CRM is that they have to use asynchronous methods when communicating with the CRM web services. Asynchronous methods and callbacks are not particularly complex concepts or even challenging to program, but real complexity arises when you have a dependency chain of asynchronous methods, leading to high volumes of heavily indented code or scattered logic that is counter-intuitive to the intended logic of the application. With the upcoming release of Visual Studio 2012, this is no longer a problem!
To ensure the UI remains responsive, Silverlight does not allow us to perform a call to the WCF endpoint whilst blocking the UI thread. This means when we perform a web service request, a thread is spawned to wait for the response. This is great for users, as it ensures their Silverlight applications do not lock up when web service queries are made. However, for developers, this can be a real headache. Multithreaded applications are far more complicated to write than single threaded ones. For one, developers need to worry about cross-thread object access; code run in a background thread needs to be dispatched back up to the UI thread before it can modify UI components. Secondly, developers are required to write callbacks to handle responses from the server. These quickly become unmanageable, especially when nested.
Asynchronous Methods & Callbacks
Typically when you retrieve data from CRM, you want to do something with the retrieved data. This could be as simple as counting the results of a query, or inspecting the value of a field. I can’t imagine a reason you would want to invoke the Retrieve or RetrieveMultiple operations and not want to inspect the returned value(s).
Let’s consider an example to demonstrate the differences between programming this synchronously and asynchronously. Let’s say you’re working with the WCF endpoint. Your requirement is to query CRM for all contacts in the system, and display their names to the user.
This is how it’s done in a synchronous way:
However, we can’t do this synchronously in Silverlight, so we’d have to write a callback to specify what needs to happen when the response is received.
So even with this simple example we can see there’s a lot of added complexity in the code. Not only is the code to send and receive the request more verbose, there’s also added complexity introduced as the response is executed on a different thread to the UI. Rather than using the IOrganizationService interface, we can use the events available to us on the OrganizationServiceClient, but the structure of the code is almost identical, with the same problems.
Taking this one step further, suppose we want to run a separate query against each of these contacts to retrieve some related information. In the asynchronous example we have to introduce another nested callback of a similar quantity. This quickly becomes unmanageable.
One approach to making this more manageable is to break the callback into a separate method. This approach goes some way to improving the maintainability of the code. However, it’s still quite verbose and we’ve still got the problem of having to dispatch back up to the UI thread in the response.
A better way
Writing code like this quickly hides the fundamental purpose of the code, making the logic very difficult to read. Wouldn’t it be great if we could write single threaded Silverlight applications without blocking the UI thread? Well now we can!
.NET 4.5 introduced new language keywords to overcome exactly this problem, and with Visual Studio 2012 we can use these keywords with Silverlight 5. These enhancements were first introduced as the Async CTP for .NET 4.0, and although the CTP is licenced for production use, it is not recommended. However, with the upcoming release of .NET 4.5, the keywords have been built into the language, and with the help of the Async Targetting Pack, we can use these features in Silverlight 5 applications.
I won’t go into huge detail on the inner workings of the new language features, rather a brief overview, but if you’re interested in some of the detail, I would highly recommend giving this video a watch.
The new async features are built on top of the TPL introduced in .NET 4.0, and introduce two new language constructs; async and await. Developers use async to indicate that a method runs asynchronously, and await to indicate that execution should pause until a task has been completed. Conveniently for Silverlight developers, this can all happen on the UI thread without having to block.
Setting It Up
The best way to demonstrate the benefits is to see it in action, but before we can do that we need to install the Async Targetting Pack. Begin by creating a new Silverlight application in Visual Studio
Then in the newly created project, select Tools -> Library Package Manager -> Package Manager Console
and in the Package Manager Console type the following and press enter:
This only takes a few seconds to install, and once complete allows you to use the new language features within your application.
For this example, I have also configured the project to use the CRM SOAP endpoint as detailed in this SDK article.
Finally, I have also created a class of extension methods that enable the IOrganizationService methods to be used asynchronously. Create a new class in your project called AsyncExtensions.cs and insert the following code. Ensure the namespace matches the one that your service reference has.
Using the New Features
Now that my project is setup, I can start using the new features to interact with CRM. Here’s the Silverlight example from above rewritten to take advantage of the new keywords:
There are several points to notice here. Firstly, notice the use of the async keyword in the method signature, this indicates that this method runs asynchronously and allows us to use the await keyword within the method body. The await keyword is used to await the results of the RetrieveMultiple extension method.
More interestingly though, there are several things to notice that are not here. Firstly, there no callbacks and all of the logic is defined within the same method body. This makes the code much more readable. Secondly, because execution is resumed on the UI thread when service.RetrieveMultiple returns a result, we do not have to dispatch back up to the UI to display the results to the user.
Also note there is nothing special required to invoke this method. Although the method is marked as asynchronous, the consuming code does not need to be aware of this:
Under The Hood
So what’s going on in the extension method that we called? For a method to be awaitable, it needs to return one of three types; void, Task or Task<T>, so to await CRM web service calls we need to wrap the available methods up into a new method that returns an awaitable type. For example, this is the RetrieveMultiple extension method used in the previous example:
The TaskCompletionSource<T> object is used to create a task of the appropriate type, which allows us to await the results of the standard BeginRetrieveMultiple method. Also note that error handling is also catered for, so if the web service throws an exception the awaiting code will be notified.
This feature does require Visual Studio 2012, which is due for launch on September 12th 2012. Unfortunately, the excellent CRM 2011 Developer Toolkit does not currently work with Visual Studio 2012, which is worth bearing in mind if you’re contemplating a switch.
This feature also requires Silverlight 5. Silverlight 5 support within CRM is not straight forward; it is not supported when embedding directly on to forms, but wrapping your SL5 XAP resources inside an HTML web resource is supported.
So there we have it, the new async features in .NET 4.5 combined with the Async Targeting Pack provide Silverlight developers with the tools to transform their asynchronous code back to readable, maintainable methods, by removing the need to litter business logic with callbacks and UI dispatching code. We’ve seen how to install and use the basic features of the language enhancements, and have used a class of extension methods that enable us to work with the CRM WCF web service with the new async features.
Visual Studio 2012 RTM is now available to download on MSDN, and I would highly recommend taking a look!