Using the asynchronous features of WCF

One issue with the previous versions of WCF was that its service contracts did not contain definitions of its asynchronous members, resulting in unnecessary complexity in the WCF code when using asynchronous calls. Furthermore, the code was prone to timeouts and error-handling issues.

There are some scenarios that require these kinds of asynchronous calls:

  • Executing multiple requests in parallel and continuing when they have finished.
  • Executing a sequence of requests and stopping if one of them fails.
  • Performing a hierarchy of operations that can occur sequentially, and also executing various requests in parallel after a given one. This is, in effect, a combination of the previous two types.

WCF 4.5 simplifies this behavior and also makes the web services easily testable.

Next, we will explore how to implement an asynchronous web service and consume it.

Getting ready

In order to use this recipe, you should have Visual Studio 2012 installed.

How to do it...

In this recipe, we will explore the new asynchronous features of WCF.

  1. First, open Visual Studio 2012, create a new project by navigating to Visual C# | Web, and use the ASP.NET Empty Web Application template to create a web project to host the web service. Name it WebAppWcfAsyncHost and click on OK.
  2. Right-click on the project and add a new item of the type WCF Service; name it AsyncService.svc and click on the Add button.
  3. Open the generated IAsyncService.cs file and replace the code with the following:
    [ServiceContract]
    public interface IAsyncService
    {
        [OperationContract]
        Task<int> DoWorkAsync();
    }
  4. Note that we will have to add a reference to System.Threading.Tasks.
  5. Open the AsyncService class and replace the code with the following:
    public class AsyncService : IAsyncService
    {
        Public async Task<int> DoWorkAsync()
        {
            return new System.Random().Next(1, 10);
        }
    }
  6. Build the application.
  7. Add a new project by navigating to Visual C# | Windows, and select the Console Application template. Name it ConsoleWcfServiceAsyncConsumer and click on the OK button.
  8. Set it as the startup project.
  9. Right-click on the newly added project and select Add Service Reference.
  10. Click on the Discover button and the provided service should appear; select it and in the Namespace field write AsyncServiceReference, as shown in the following screenshot, and click on the OK button.
    How to do it...
  11. Open the Program.cs file in the designer and enter the following code:
    class Program
    {
        Static AsyncServiceClient svcCli = new AsyncServiceClient();
    
        static void Main(string[] args)
        {
            Console.WriteLine("Requesting values");
            var result = GetResultsFromWebService();
            Console.WriteLine("The result is: " + result.Result.ToString());
            Console.ReadLine();
        }
    
        Static async Task<int> GetResultsFromWebService()
        {
            var t1 = svcCli.DoWorkAsync();
            var t2 = svcCli.DoWorkAsync();
            var t3 = svcCli.DoWorkAsync();
            var t4 = svcCli.DoWorkAsync();
    
            Console.WriteLine("Waiting for all the values to be returned..");
            await Task.WhenAll(t1, t2, t3, t4);
    
            Console.WriteLine("All the values received, processing..");
            return t1.Result + t2.Result + t3.Result + t4.Result;
        }
    }
  12. Press the F5 key to start executing the program. We should see the result of our program in the console as shown in the following image:
    How to do it...
  13. We have just created an asynchronous WCF service, called it asynchronously many times, and synchronized the reception of the different web service calls.

How it works...

Essentially, the only different thing we did was to add the Task<int> command to the WebService method declaration; the rest simply works out of the box.

On the client side, we called our random asynchronous value provider four times and assigned the results to the tasks. We then used the Task.WhenAll() method to wait for the tasks, so the code will not continue running this method until all the tasks have finished; this means that all the web service calls have returned.

Although this example might seem simple, imagine that you changed the random integer services with other possible services, such as GetOrderTotal, GetOrderTaxes, or GetOrderShippingCosts, and you will begin to see the possibilities. This new coding style simplifies our code noticeably, and makes it easier to maintain and understand.

The Task-Based Asynchronous Pattern that we have just seen is clearly superior to and simpler than the previous event-based patterns and IASyncResult asynchronous patterns.

We should use this pattern as the preferred way to implement any WCF asynchronous operation.

It is also important to keep in mind that the use of this pattern is beneficial for scalability since it assures that thread-related resources are only consumed when the code is being executed. An asynchronous solution will allow the thread resources to be used by other means while waiting for I/O, database operations, or other services to complete. When the operation is complete, it will yield the necessary data for the operation to continue.

See also

Look into the Understanding async and await in .NET 4.5 recipe of Chapter 2, Exploring the Top New Features of the CLR, dedicated to CLR and the usage of async and await.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset