Saturday, May 7, 2011

WCF Asynchronous Services

During a design session the other day someone was asking what are the possibilities for asynchronous calls in WCF.  There are are number of ways to do it, each with different attributes.

  1. When referencing a standard WCF service from the client using the advanced options (of the Visual Studio add service reference dialog) you can generate BeginInvoke and EndInvoke methods. This allows for an "IAsyncResult invocation pattern" (check out MSDN - Invoking synchronous methods asynchronously and good article on Code Project explaining asynchronous calls).  Essentially you pass in a call-back that will be called when the method returns, and they you are able to retrieve the method result from the IAsynResult argument provided. This gives a clientside WCF service consuming developer the option to execute standard synchronous WCF services asynchronously. Great if you do not have control over the service. Also ideal if the expected delay between request and response is not larger than 60 seconds or so.

  2. A standard WCF service can be decorated with IsOneWay=true in the OperationContract attribute. This effectively tells WCF to immediately return the thread back to the caller.  No return values or response is possible from such a service, including exceptions. These are fire and forget style services (sometimes called Document Services).

  3. The most advanced and flexible way is using Callback Contracts. This requires another Contract be defined and specified with the requesting ServiceContract. Also known as Duplex services.  Usually the Operations are also decorated IsOneWay=True, indicating that the calling thread is released back to the client immediately.  These are ideal when writing a publish/subscribe pattern and the response will be sent back to the client at some future point at an unknown time. It could be minutes or hours, or it could generate 100 responses over time for one "subscribe" request. Its almost like an event subscription.  See the MSDN article referenced below for more info.
    *EDIT* I would recommend avoiding using this pattern if possible, a far more robust way of achieving the same results without resorting to Singletons is using MSMQ.  A common way to deal with long-running Duplex services is to make them singletons to be able to store the callbacks.  You can avoid this by create a class to manage the callbacks, but then this class effectively becomes a singleton.  A far simpler pattern is to take advantage of MSMQ.

Its also worth noting that when searching for Asynchronous method and service invocation patterns the Reactive (Rx) framework seems to come up a lot.  This was a framework that was pioneered by a team at Microsoft to "clean-up" code that needs to call methods asynchronously. Its kind of like Linq over Events, and they succeeded in making calling code more elegant.  However it has been superseded by the Task Parallel Library (TPL) in .NET 4, more specifically the Task Factory and associated classes.  Some say this is not so, but essentially in my humble opinion what can be done out of the box in .NET 4 without an extension framework is the best way to go.


References:

No comments:

Post a Comment