Monday, July 15, 2013

Asynchronous Patterns in CRM2011- Part 1

Last few weeks, I am trying my hands on creating windows 8 apps for CRM. I was going through a sample solution posted on http://blogs.msdn.com/b/crm/archive/2013/05/28/new-blog.aspx. The most important part of the sample solution is the two projects “WinRt.Microsoft.Crm.Sdk” and “WinRt.Microsoft.Crm.Sdk.Proxy”. These projects are updated versions of  the original SDK dlls to work with windows 8 apps. They have implemented the Event Based Asynchronous Pattern (EAP) to make OrganizationServiceProxy methods to work asynchronously.
I decided to write something about Async patterns and here we go. There are 3 types asynchronous programming patterns.
  • APM – Asynchronous Programming model
It is also known as IAsyncResult pattern. It requires a begin and an end method. For example BeginExecute() and EndExecute() methods. We generally calls the end method in the callback method. You can find the examples of this pattern in the Silverlight samples of CRM 2011 SDK  .
  • EAP – Event based Asynchronous Pattern
The event based asynchronous pattern consist of function/s  Async suffice (MethodNameAsync). These async function/s may have MethodNameCompleted event, which will be raised when the operation is completed. For more info please have a look at the http://msdn.microsoft.com/en-us/library/wewwczdw.aspx.
  • TAP - Task based Asynchronous Pattern
Task based is introduced from .NET 4.0. The Task-based Asynchronous Pattern (TAP) is based on the Task and Task<TResult> types in the System.Threading.Tasks. The biggest difference in TAP, APM and EAP is the initiation and completion of the async operation in a same method.
TAP is the recommend pattern for future development. In this blog we will talk about using TAP for CRM2011 applications that need async calls for example Silverlight and windows store apps.

Why use TAP

As mentioned above in TAP section, the biggest problem the with APM and EAP patterns is initiation and completion of the operation in separate methods.  This force us to put the program logic in different methods.  It makes the code difficult to read.
The good thing about TAP is that it is very easy to write a wrapper for APM and EAP and expose them as TAP implementations. This word document contains a lot of information about TAP.

Consuming the TAP pattern in VS2012

In .Net framework 4.5 TAP pattern can be consumed using a keyword “await”. An await expression must occur inside the body of an asynchronous method, with return type void, Task, or Task<TResult> for some TResult. The await keyword can also be used with .Net frame work 4.0 and Silverlight 5 by using Async Targeting Pack for Visual Studio 2012.
There are also other ways to consume TAP pattern by using methods like “ContinueWith” and “ContinueWhenAll”. For sample code have a look at the Mike Snider’s blog.

Using TAP pattern in Silverlight 5 and CRM2011

In this blog we will talk about how to use TAP pattern with CRM2011 and Silverlight 5. I am going to use  soapforsilverlight sample located at \sdk\samplecode\cs\silverlight\soapforsilverlight of CRM2011 SDK.
If we look at the code we can see the sample is using the following 2 methods to retrieve and display the accounts names. These methods are defined in MainPage.cs file.

        private void AccountList_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                QueryExpression query = new QueryExpression()
                {
                    EntityName = "account",
                    ColumnSet = new ColumnSet()
                    {
                        Columns = new System.Collections.ObjectModel.ObservableCollection<string>(new string[] { "name" }) 

                    },
                    Orders = new System.Collections.ObjectModel.ObservableCollection<OrderExpression>(new OrderExpression[]
                {
                    new OrderExpression() { AttributeName = "name", OrderType = OrderType.Ascending }
                })
                }; 

                query.PageInfo = new PagingInfo { Count = MaxRecordsToReturn, PageNumber = 1, PagingCookie = null }; 

                OrganizationRequest request = new OrganizationRequest() { RequestName = "RetrieveMultiple" };
                request["Query"] = query; 

                IOrganizationService service = SilverlightUtility.GetSoapService(); 

                service.BeginExecute(request, new AsyncCallback(AccountList_ClickCallback), service);
            }
            catch (Exception ex)
            {
                this.ReportError(ex);
            }
        } 

        private void AccountList_ClickCallback(IAsyncResult result)
        {
            try
            {
                OrganizationResponse response = ((IOrganizationService)result.AsyncState).EndExecute(result);
                EntityCollection results = (EntityCollection)response["EntityCollection"]; 

                StringBuilder sb = new StringBuilder();
                if (results.Entities.Count == 0)
                { sb.AppendLine("There are no Account records in the system."); } 

                foreach (Entity entity in results.Entities)
                {
                    sb.AppendLine("Account Name = " + entity.GetAttributeValue<string>("name"));
                }
                if (results.MoreRecords)
                {
                    sb.AppendLine("Only the first " + MaxRecordsToReturn + " records were returned.");
                }
                this.ReportMessage(sb.ToString()); 

            }
            catch (Exception ex)
            {
                this.ReportError(ex);
            }
        } 


There are two methods “BeginExecute” and “EndExecute” which represent the initiation and the completion of the “Execute” operation.  The “EndExecute” is called in the callback method.

Now we are going to write a TAP wrapper for this code. The BeginExcecute method is taking 3 parameters request, callback method and IOrganizationService. We are going to do the same in our wrapper code.

public static Task<OrganizationResponse> Execute(OrganizationRequest request,IOrganizationService service)
        {
            var tcs = new TaskCompletionSource<OrganizationResponse>(); 

            service.BeginExecute(request, (asyncResult) =>
            {
                try
                {
                    tcs.SetResult(((IOrganizationService)asyncResult.AsyncState).EndExecute(asyncResult));
                }
                catch (Exception ex)
                {
                    tcs.SetException(ex);
                }
            }, service); 

            return tcs.Task;
        } 

    } 


TaskCompletionSource is required to get the completed async task. The completion can represents the successful completion of the call, any exceptions and cancellation of the process etc.

TaskCompletionSource exposes 2 methods to set result. We are using tcs.SetResult. You can use TrySetResult. The same applies to set the exception for TaskCompletionSource.

Now we have a TAP wrapper. As I explained earlier, we would like to call this method using await keyword and to do that we need to create an asynchrous method. So here is my asynchronous method.
 
        //async function
        private async void getAccount()
        {
            try
            {
                QueryExpression query = new QueryExpression()
                {
                    EntityName = "account",
                    ColumnSet = new ColumnSet()
                    {
                        Columns = new System.Collections.ObjectModel.ObservableCollection<string>(new string[] { "name" })

                    },
                    Orders = new System.Collections.ObjectModel.ObservableCollection<OrderExpression>(new OrderExpression[]
                {
                    new OrderExpression() { AttributeName = "name", OrderType = OrderType.Ascending }
                })
                };

                query.PageInfo = new PagingInfo { Count = MaxRecordsToReturn, PageNumber = 1, PagingCookie = null };

                OrganizationRequest request = new OrganizationRequest() { RequestName = "RetrieveMultiple" };
                request["Query"] = query;

                IOrganizationService service = SilverlightUtility.GetSoapService();

                //calling the TAP wrapper
                var task = await Execute(service, request);

                // Get the results from the task
                var response = task.Results;

                //Manipulating the result
                EntityCollection results = (EntityCollection)task.Results[0].Value;

                StringBuilder sb = new StringBuilder();
                if (results.Entities.Count == 0)
                { sb.AppendLine("There are no Account records in the system."); }

                foreach (Entity entity in results.Entities)
                {
                    sb.AppendLine("Account Name = " + entity.GetAttributeValue<string>("name"));
                }
                if (results.MoreRecords)
                {
                    sb.AppendLine("Only the first " + MaxRecordsToReturn + " records were returned.");
                }
                this.ReportMessage(sb.ToString());
               
            }
            catch (Exception ex)
            {
                this.ReportError(ex);
            }


        }
I have added the contents of AccountList_Click and AccountList_ClickCallback methods to create this async method. As we can see we can get the result of the call in the same method. Now I will call this method in AccountList_Click.

        private void AccountList_Click(object sender, RoutedEventArgs e)
        {
           // calling the async method   
            getAccount();
        }
You are good to go. Please leave some feedback. In next part we will try to create a TAP wrapper for EAP pattern.

1 comment: