Visual Studio async CTP with Silverlight
Well, silverlight applications have a lot of asynchronous operations (WCF, WCF RIA operations, etc.), I recall a project in which I had to do this procedure: download a set of users asynchronously, if the download was not successful, do some finishing operations, else download a set of customers, if the download was not successful, do some finishing operations, else download a set of streets….A HELL OF DIFFERENT FUNCTIONS in a class for just a bunch of simple operations.
Hopefully, visual studio async CTP is here to solve these kind of problems once and for all. It is a way to make asynchronous operations look like they are synchronous. For more information have a look here. You can download it from here.
Together we are going to see two examples, one using a simple WCF service and one using WCF RIA services.
Simple WCF service
Lets create a wrapper class for bing maps services. In this class we’ll add a function that takes an address name as a parameter and returns a Geocode result. First, if you downloaded the library correctly, then you should have a folder that contains .dll files which are appropriate for the async CTP to run. Add a reference to the AsyncCtpLibrary_Silverlight library and add a new class with the following function:
1: public Task<GeocodeResult> GetGeocode(string address)
3: GeocodeServiceClient service = new GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
4: TaskCompletionSource<GeocodeResult> task = new TaskCompletionSource<GeocodeResult>();
6: GeocodeRequest request = new GeocodeRequest();
7: request.Credentials = new Microsoft.Maps.MapControl.Credentials();
8: request.Credentials.ApplicationId = Credentials.Key;
10: request.Query = address;
12: service.GeocodeCompleted += (s, e) =>
14: if (e.Error != null || e.Result.Results.Count == 0)
15: task.TrySetException(new Exception("Η περιοχή \"" + address + "\" δε βρέθηκε"));
16: else if (e.Cancelled == true)
22: service.GeocodeAsync(request, address);
24: return task.Task;
You may see some new stuff here:
It’s the class that is used to wait for an asynchronous operation to finish.
A call to an asynchronous WCF service function lets us pass a user state parameter, so we pass this kind of object as a user state and gets filled when the function ends (task.TrySetResult(e.Result.Results);) ).
What is finally returned from this wrapper function is a task, lets see now how we can use it. A function that calls the previous wrapper function may look like this:
1: private async void CalculateRoute()
3: GeocodeResult result = await _calculator.GetGeocode(address);
Here you can see two new keywords:
Each function that uses the async CTP must contain this keyword in its definition and must be void.
With this keyword we actually turn an asynchronous call into a synchronous one, more specifically, we wait for an asynchronous call to finish and take the object that returns.
I hope you like the async CTP because we just got warmed up !
WCF RIA Services
Well, usage of async CTP is a bit more complex with WCF RIA services, but thanks to Kyle McClellan, in this post he created an extension method for embedding the async CTP task in the RIA services contexts, and this extension method is the following:
1: public static class OperationExtensions
3: public static Task<T> AsTask<T>(this T operation)
4: where T : OperationBase
6: TaskCompletionSource<T> tcs =
7: new TaskCompletionSource<T>(operation.UserState);
9: operation.Completed += (sender, e) =>
11: if (operation.HasError && !operation.IsErrorHandled)
16: else if (operation.IsCanceled)
26: return tcs.Task;
And now, we can call domain service context methods like this:
1: MyContext context = new MyContext();
3: LoadOperation<MyModel> operation = await context.Load<MyModel>(context.DownloadModelsQuery()).AsTask();
4: foreach (MyModel model in operation.Entities)
This is all for today ! I hope you like the async CTP !! Happy new year and have a nice time !!