What about WCF 4.5 and the async/await pattern?
From what I’ve heard it should be pretty smooth to produce asynchronous server/client code with .net 4.5, so let’s try it out! Defining async methods on the service contract is now a lot cleaner :
[ServiceContract]
public interface IPeopleService
{
	[OperationContract]
	Task<IList<Person>> GetPeople();
}
instead of the wcf 4.0 way which would look something like this :
[ServiceContract]
public interface IPeopleService
{
	[OperationContract(AsyncPattern=true)]
	IAsyncResult BeginGetPeople(AsyncCallback cb, object state);
	[OperationContract]
	IList<Person> GetPeople();
	[OperationContract]
	IList<Person> EndGetPeople(IAsyncResult ar);
}
the server side implementation of the operation when returning a task is straightforward :
public async Task<IList<Person>> GetPeople()
{
	Task t1 = Task.Delay(500);
	Task t2 = Task.Delay(500);
	await Task.WhenAll(t1, t2);
	return await Task.Factory.StartNew(() => people);
}
If you don’t want to await something in the method you can skip the async keyword and still return a Task as shown below, async on a method simply tells the compiler that “I’m going to await something in this method”.
public Task<IList<Person>> GetPeople()
{
	return Task.FromResult(people);
}
Anyways it’s really nice to skip the non-implemented begin/end methods on the server which was simply boiler plating in .net 4.0. For the sake of simplicity the service will be hosted in a console application and for consuming the service I’ve implemented a simple proxy that inherits ClientBase<TChannel> and implements the contract. See the code if this confuses you (which probably means that you’re a noob ;-)). The client code when working with tasks is clean and straightforward as well :
var serviceProxy = new PeopleServiceProxy("PeopleServiceEndpoint");
Task<IList<Person>> people = serviceProxy.GetPeople();
people.ContinueWith(
	x =>
		{
			foreach (Person person in x.Result)
			{
				Console.WriteLine(
					"{0} {1} born {2}",
					person.FirstName,
					person.LastName,
					person.BirthDate.ToShortDateString());
			}
		});
We can control on which thread we will continue by passing in a TaskScheduler. So far so good, so what about testing? I’m using Nunit which integrates really well with VS when using resharper. I want to write an integration test (not unit) to make sure everything works well including the WCF part since unit testing my simple service is too easy ;-) I’ll host the service in the Setup method and take it down in the teardown. A simple test then looks like :
[Test]
public void ShallBeAbleToGetDateTimeFromService()
{
	IPeopleService serviceProxy = new PeopleServiceProxy("PeopleServiceEndpoint");
	Task<IList<Person>> getPeopleTask = serviceProxy.GetPeople();
	getPeopleTask.Wait();
	IList<Person> result = getPeopleTask.Result;
	Assert.IsNotNull(result);
	Assert.AreEqual(2, result.Count);
	(serviceProxy as IDisposable).Dispose();
}
Obviously we’d use facades to call on services in a real application but the principle is the same. It doesn’t get much cleaner than this imo.
/A


Leave a Reply
Want to join the discussion?Feel free to contribute!