Asynchronous proxy for a synchronous WCF service

I recently had this scenario while working for a client where we wanted to consume a synchronous service asynchronously. We couldn’t change the service contract since it would break other proxy implementations. Luckily conventions implemented by the guys at microsoft made this task surprisingly easy, this is how we solved it.

Let’s say our service contract looks like this:

[ServiceContract]
public interface IService1
{
    [OperationContract]
    string GetData(int value);
}

With the following service implementation:

public class Service1 : IService1
{
    public string GetData(int value)
    {
        return string.Format("You entered: {0}", value);
    }
}

An synchronous proxy would look something like this:

class ServiceClient : IService1
{
    private readonly IService1 _channel;

    public ServiceClient()
    {
        var factory = new ChannelFactory(binding, address);
        _channel = factory.CreateChannel();
    }

    public string GetData(int value)
    {
        return _channel.GetData(value);
    }
}

And consuming it synchronously is trivial:

var client = new ServiceClient();
var data = client.GetData(10)

So how do we consume this asynchronously? We simply define a parallel async service contract with the same ServiceContract name, like this:

[ServiceContract(Name = "IService1")]
interface IService1Async
{
    [OperationContract]
    Task GetDataAsync(int value);
}

And an asynchronous proxy would look something like this:

class ServiceClientAsync : IService1Async
{
    private readonly IService1Async _channel;

    public ServiceClientAsync()
    {
        var factory = new ChannelFactory(binding, address);
        _channel = factory.CreateChannel();
    }

    public Task GetDataAsync(int value)
    {
        return _channel.GetDataAsync(value);
    }
}

And consuming it asynchronously becomes trivial:

var client = new ServiceClientAsync();
var data = await client.GetDataAsync(10);

To summarize: The convention is as long as the service name is the same on the contract the method will be called if the method name matches and also if you’ve appended Async to the method name. Pretty smooth imho, and all without the need to change the “legacy service” contract.

Cheers!

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *