This is the second in a series of posts about the AsyncPattern in WCF.
However, a question still remains: when and how to use AsyncPattern = true on the service-side?
- The WCF documentation states that
“Use an asynchronous approach in a service operation implementation if the operation service implementation makes a blocking call, such as doing I/O work. When you are in an asynchronous operation implementation, try to call asynchronous operations and methods to extend the asynchronous call path as far as possible
- Similarly, Kenny Wolf (from the WCF/WF group) states that
and also that
If you aren’t doing something that’s “natively async”, then you shouldn’t be using AsyncPattern=true. That is, you shouldn’t just create a thread just for the sake of performing “background work” as part of an asynchronous operation
My conjecture is that asynchronous operation implementation should be used when there are conditions to release the calling thread, without requiring the creation of a new thread, and the time needed for the operation completion is significant. This happens when the operation performs “lengthy” IO requests. If the IO interface has an asynchronous interface, then the asynchronous operation call can be “linked” to the asynchronous IO call (see diagram below). Note that a service request is just a special kind of an IO request and that WCF also provides an asynchronous interface for clients.
The following sequence diagram shows the “linkage” between the asynchronous operation implementation and an asynchronous IO request.
- The WCF dispatcher calls the BeginOperation method, which in turn starts the asynchronous IO request (BeginIO) and returns immediately,. This sequence is done on an IO thread, which is “released” after BeginOperation returns.
- When the IO request is completed, the Operation Callback is called on an IO thread (not necessarily the same from the above sequence). This callback:
- Calls EndIO to finish the IO request and collects the IO result.
- Calls the WCF provided callback (passed as a parameter to BeginOperation).
- The WCF callback then calls EndOperation to finish the operation and collect the operation result.
Notice that the operation’s execution is divided into two sequences (two threads):
- The “left-to-right” sequence processes the request, running on the IO thread associated with the service request.
- The “right-to-left” sequence produces the reply, running on the IO thread associated with the IO request completion.
Namely there is no blocked thread between the start of the operation and the completion of the IO. This property is important in scenarios were there can be a significant amount of operations waiting for “lengthy” IO requests (e.g. middle-tier services).