Following are my notes from a WCF asynchrony demo I worked up a while back... thought it might interest somebody.
This WCF example works with the AdventureWorks demo database in SQL 2005. It illustrates mixing and matching synchronous and asynchronous processing in a WCF service and client. Specifically, the code shows:
- synchronous client code invoking synchronous service code ( not a big deal, admittedly
)
- synchronous client code invoking asynchronous service code
- asynchronous client code invoking synchronous service code
- asynchronous client code invoking asynchronous service code
Support for asynchrony is baked directly into the WCF contract (interface definition) using the AsyncPattern property of OperationContractAttribute. Such an interface also must adhere to the .NET asynchronous execution pattern (BeginXXX and EndXXX method pairs, use of IAsyncResult call object, support for callbacks, etc.). Here's the contract definition from the demo (edited down a bit for easy reading):
[ServiceContract]
public interface IAdventureWorksDataServiceAsync
{
[OperationContract(AsyncPattern=true)]
IAsyncResult BeginGetSalesPersonData(AsyncCallback cb, object state);
SalesDataTable EndGetSalesPersonData(IAsyncResult result);}
[ServiceContract]
public interface IAdventureWorksDataServiceSync
{
[OperationContract]
SalesDataTable GetSalesPersonData();
}
The important point here is that sync/async processing is a local implementation detail of clients and/or services. With WCF, the choice of synchronous/asynchronous processing on one end of the wire need not surface in the programming model on the other end. The demo client code can make calls against IAdventureWorksDataServiceSync, and the server can process such requests on an object that implements IAdventureWorksDataServiceAsync, or vice versa.
Think about that for a moment... it's pretty cool that the WCF infrastructure gives this to us for the cost of a few attributes. It's not unlike async page processing in ASP.NET, where the client just types in a URL and has no idea that special ThreadPool magic is happening on the server.
A few additional points:
- Notice that, in the cases where you have sync <==> async processing (or vice versa), the client and server endpoint contracts don't reference the exact same physical interface definition; "matching" client and server contracts must be type-compatible, but not necessarily modeled on the exact same interface.
- The server-side benefits to async processing are primarily 2 fold: 1) separate the resources (threads, in this case) needed for accepting requests from the resources (threads) needed to process requests, and 2) spend as little time as possible accepting requests (as opposed to processing them, which "takes as long as it takes").
- The oft-repeated client-side benefit to async processing is the ability to not tie up a UI thread waiting for a remote request to return a response. The demo illustrates this.
- For a bit of insight into what happens inside ThreadPool, pay attention to the console output of Host.exe, and take a look at the async Start and End methods on the server side.
Enjoy!