In WCF, asynchronous operations can be implemented by using one of the three following methods:
Today I am going to explain how to implement asynchronous operations in WCF using each of these methods using some examples. In here I will not be covering the basics of WCF and I assume you all have some experience with programming WCF before. So I will start off with the event-based pattern.
I have created a WCF Service Application and I have the default WCF service and it’s interface and I am modifying the service and it's contract as follows.
iService1.cs
[ServiceContract]
public interface IService1
{
//event-based asynchronous pattern
[OperationContract]
string GetData(string message);
}
Service1.cs
public class Service1 : IService1
public string GetData(string message)
Thread.Sleep(5000);
return message;
As you can see, In my service contract I have exposed a very simple method which will accept string and return a string. In my service I have it implemented and I have put a thread sleep, just for demonstration purposes.
Now I have my client console application and I am adding a Service Reference to this service. A thing to note here is I am enabling "Allow generation of asynchronous operations" and under that I am enabling "Generate asynchronous operations".
Add Service Reference
Generate Asynchronous Operations
When this is selected only, the proxy class will contain relevant methods for asynchronous operations for both event-based asynchronous pattern and IAsyncResult asynchronous pattern.
Now let’s see the client side code.
class Program
static wsService1.Service1Client client1 = new wsService1.Service1Client();
static void Main(string[] args)
client1.GetDataCompleted += client_GetDataCompleted;
client1.GetDataAsync("event-based asynchronous pattern");
Console.WriteLine("Waiting for async operation...");
Console.ReadLine();
static void client_GetDataCompleted(object sender, wsService1.GetDataCompletedEventArgs e)
Console.WriteLine(e.Result.ToString());
In here what happens is first I am subscribing to the GetDataCompleted method. When the GetDataAsync Method has completed, client_GetDataCompleted event will be triggered. If you notice the control flow here, the operations in the server are still done synchronously, but operations in the client are done asynchronously. Finally the output will be as follows, first it will print the “Waiting for async operation” and then it will print the message returned from the service.
Output
The second way of implementing WCF service operation in an asynchronous fashion is marking the <Begin> method with the AsyncPattern property set to true. In this case, the asynchronous operation is exposed with two additional methods;
We can further divide this IAsyncResult asynchronous pattern into two sub models. That is,
For this Client-Side Asynchronous model, I will take the same WCF Service I got for demonstrating event-based asynchronous pattern.
Now in my client console application I am using the same service reference.
client1.BeginGetData("IAsyncResult asynchronous pattern (Client-Side)", new AsyncCallback(GetDataCallBack), null);
static void GetDataCallBack(IAsyncResult result)
Console.WriteLine(client1.EndGetData(result).ToString());
In here, I am calling the BeginGetData method which is generated by the proxy. It will always have it’s first parameter as the same parametes in the method I am calling asynchronously, plus two additional parameters. The second parameter is an AsyncCallback delegate that references a method to be called when the BeginGetData completes.The third parameter is a object which contain state about the asynchronous operation. So when my asynchronous BeginGetData completed, my callback method will be called. In my callback method I am calling the EndGetDate method (again which is generated by the proxy) to end the asynchronous operation and to retrieve the results.
Again the output will be as follows: first it will print the “Waiting for async operation” and then will print the message returned from the service.
The Both-Side Asynchronous model of IAsyncResult asynchronous pattern is little bit different. In here we have both client side and server side operations asynchronous. If you have been reading the post carefully, when I am introducing the IAsyncResult asynchronous pattern, I have mentioned about setting AsyncPattern property to true to the begin method. And to above Client Side Asynchronous model of IAsyncResult asynchronous pattern, I didn't do that. Now let’s take a look at the following model.
I am creating a new WCF service.
iService2.cs
public interface IService2
//IAsyncResult asynchronous pattern
[OperationContractAttribute(AsyncPattern = true)]
IAsyncResult BeginWorkerMethod(string message, AsyncCallback callback, object asyncState);
string EndWorkerMethod(IAsyncResult result);
Service2.cs
public class Service2 : IService2
public IAsyncResult BeginWorkerMethod(string message, AsyncCallback callback, object asyncState)
var task = Task<string>.Factory.StartNew((res) => MyMethod(asyncState,message), asyncState);
return task.ContinueWith(res => callback(task));
public string EndWorkerMethod(IAsyncResult result)
return ((Task<string>)result).Result;
private string MyMethod(object asyncState,string message)
In my Service interface, I have defined two methods using the pattern BeginOperation and EndOperation. Please note that the OperationContractAttribute attribute is applied only to the BeginWorkerWork method.
In the service, I have implemented these two methods. In here I have used Tasks for asynchronous operation. I have a callback method and which will called when the task is completed.
And in the client side I have the following code.
static wsService2.Service2Client client2 = new wsService2.Service2Client();
client2.BeginWorkerMethod("IAsyncResult asynchronous pattern (Server-Side)", new AsyncCallback(GetDataCallBack), null);
Console.WriteLine(client2.EndWorkerMethod(result).ToString());
The output is the same: first it will print the “Waiting for async operation” and then it will print the message returned from the service.
The task-based asynchronous pattern is the preferred way to implement asynchronous operations because it is the easiest and most straight forward. But the only thing is async/await was introduced with .NET framework 4.5. To demonstrate task-based asynchronous pattern, I am creating new WCF service.
iService3.cs
public interface IService3
//task-based asynchronous pattern
Task<string> MyWorkerMethodAsync(string message);
Service3.cs
public async Task<string> MyWorkerMethodAsync(string message)
return await Task.Factory.StartNew(() => MyMethod(message));
private string MyMethod(string message)
Now in my client console application when I am adding a Service Reference I am enabling "Allow generation of asynchronous operations" and under that I am enabling "Generate task-based operations".
Generate Task-Based Operations
Now let’s see the client side code. Please make sure to change the Clients’ targeted framework to .NET Framework 4.5. In the client I have a async method and inside the async method, the await operator is applied to a task to suspend execution of the method until the task is completed.
static wsService3.Service3Client client3 = new wsService3.Service3Client();
InvokeAsyncMethod("task-based asynchronous pattern");
static async void InvokeAsyncMethod(string message)
Console.WriteLine(await client3.MyWorkerMethodAsync(message));
The output is the same: first it will print the “Waiting for async operation” and then will print the message returned from the service.
And that's basics of asynchronous operations in WCF. I am attaching the sample code to my sky drive, you can download and play around.
Happy Coding.
Regards,
Jaliya
Maheshkumar S Tiwari edited Original. Comment: Added tags
Does WCF support the notion of task-based asynchrony but only on the server side? That is, I want to be able to implement my WCF operation as an async method using await, but I only want to expose a synchronous method to my clients? I would like to do this because I want optimized usage of threads on the server (which the async implementation should support), but my clients are not .NET, and so it is more straightforward for them to handle synchronous methods. From a coding perspective wait I want is:
public string ComplexStringComputation(string s);
But on the implementation side I want to write:
public async Task<string> ComplexStringComputation(string s) { ... calls to other async methods ... }
So I want the WCF infrastructure to see that the operation is exposed as a synchronous operation, but that its implementation is async, and I want it to deal with that (and by 'deal with that' I mean more or less that it should register an OnComplete() callback on the Awaiter for the result of ComplexStringComputation, and then marshall the result back to the client in that callback).
If I understand async correctly, this should allow the incoming WCF request thread to be freed up while ComplexStringComputation() carries out various tasks in a manner that don't result in threads needlessly blocking. This will allow a larger number of incoming WCF requests to be serviced on a smaller number of threads.