WCF Async without proxies
I don't like generated proxies for web services, they are generally ugly and not fun to work with. However, up until recently I believed that I had to deal with them if I wanted to use the async operations for web services. As it turn out, I was wrong.
We can actually define an WCF service interface like this:
[ServiceContract] public interface IAsyncBus { [OperationContract(AsyncPattern = true)] IAsyncResult BeginProcess(IMessage[] request, AsyncCallback callback, object asyncState); IMessage[] EndProcess(IAsyncResult result); }
Now you can work with it using:
IAsyncBus bus = new ChannelFactory<IAsyncBus>().CreateChannel(); ar = bus.BeginProcess(...); //do work bus.EndProcess(ar);
The problem with that is that on the server side, I also have to do things in an async manner. This is sometimes appropriate, but it tends to be a major PITA for a lot of things.
As it turn out, we can solve the issue with aliasing. In the interface dll, we can define:
[ServiceContract] public interface IBus { [OperationContract] IMessage[] Process(IMessage[] request); } [ServiceContract(Name="IBus")] public interface IAsyncBus { [OperationContract(AsyncPattern = true)] IAsyncResult BeginProcess(IMessage[] request, AsyncCallback callback, object asyncState); IMessage[] EndProcess(IAsyncResult result); }
Now, you can create an instance of IAsyncBus to communicate with IBus directory. On the server side, we implement IBus, and handle the message in a synchronous manner. Easy, simple, and doesn't require any proxies :-)
Comments
Very nice. I was completely unaware of this.
Outstanding, I'm going to go delete my proxy based code and refactor to this.
Hi. You might be interested in this alternative to using a proxy or a channel.
http://www.acorns.com.au/blog/?p=113
Johnny,
Actually, I would probably use the Castle's WCF integration facility for this in real scenarios
That's my preference as well, although I'm not completely familarised with it yet.
It's an interesting piece of code though. I like the approach. I HATE the generated proxies - they're such a p-i-t-a to manage, I find.
Hello,
Async pattern is a nice ability that WCF supplies but as far as I know the server doesn't have to know about the AsyncPattern you are using for your clients.
Your code will work fine without the second contract. For your client you have to declare the AsyncPattern on your service contract mehods and when you implementing it you just have to call the standard Process method – WCF engine will do the rest for you.
You can see implementation of this pattern by running svcutil.exe with your mex address and apply /async parameter on it. You will get fully generated proxy with async pattern implemented for each and every of your contract methods, while in the serve you don’t mention anything about it.
Nati,
The point here is to avoid having to generate a proxy
Hey,
My point was to show that there is no need to write the second contract, like you did. I referenced you to generated code only for proof my concept; you don’t have to use it.
BTW, if you don’t use the generated code and your contract is changed, how do you get the newer one for your client?
Comment preview