Tuesday 14 August 2012

RIA: Load ComplexObject with async CTP


Async ctp is great but is not integrated with RIA services yet. Usualy we write a loadOperation from the domain context and then perform some task when the completed event is raised.  With the async ctp you can write the code as you would usualy do in a synchronous context allowing you to write code in a logical order.  

One very useful class I found and currently use is one created by Kyle McClellan, explained on his blog: http://blogs.msdn.com/b/kylemc/archive/2010/11/02/using-the-visual-studio-async-ctp-with-ria-services.aspx

This extension static class is very simple to use and brings the async functionalities to load entities from your DomainContext. 

One feature it’s missing is the ability to load a non-persisted class that is not an entity. When you reference a complex type in a function, the RIA generated class for your client interface will inherit it to a ComplexObject. 

Using the same approach described above, I created a load wrapper extension method that will return the complex type from a query asynchronously.
 public static class DomainContextExtension
    {
        public static Task<T> LoadComplexObjectAsync<T>(this DomainContext source, InvokeOperation<T> task) where T : ComplexObject
        {
            TaskCompletionSource<T> taskCompletionSource = new TaskCompletionSource<T>();
       
            Action<InvokeOperation<T>> callback =
                cb =>
                {
                    if (cb.HasError && !cb.IsErrorHandled)
                    {
                        taskCompletionSource.TrySetException(cb.Error);
                        cb.MarkErrorAsHandled();
                    }
                    else if (cb.IsCanceled)
                    {
                        taskCompletionSource.TrySetCanceled();
                    }
                    else
                    {
                        taskCompletionSource.TrySetResult(cb.Value);
                    }
                };


            var op = ((InvokeOperation<T>)(source.InvokeOperation(task.OperationName, typeof(T), task.Parameters, true, callback, null)));


            return taskCompletionSource.Task;
        }
   }

No comments:

Post a Comment