When to use Async Service Operations

I was recently asked about the motivation for choosing asynchronous service operations in WCF (i.e. [OperationContract(AsyncPattern = true)]).

If you have an operation that is blocking (accessing SQL, Channels, etc) then you should use AsyncPattern=true.  That way you’ll free up whatever thread we’re using to call your operation from. The general idea is that if you have a blocking call then you should use the async version and it should transparently play well with us.

Put another way: if you are calling a method that returns an AsyncResult (i.e. you’re accessing SQL, or using sockets, files, or channels), then you can wrap that IAsyncResult and return it from the BeginXXX call (or return the raw asyncresult depending on your scenario).

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. Note that it is legitimate to spawn a thread because your operation happens to kick off work that is outside of its completion scope (though in that case you should just have a synchronous method, not an async one).

6 thoughts on “When to use Async Service Operations

  1. dominick

    Hi Kenny,

    my understanding was that WCF requests already run on IO completion port threads (IO thread pool) which already have the characteristics to optimize work when waiting for IO.

    In ASP.NET you typically use async handler to free up a worker thread (and dispatch to an IO thread instead). But worker threads are a very sparse resource – whereas WCF has 100 IO threads by default.

    So I wonder what’s the benefit in WCF using async pattern? On which thread pool does the async work end up?

    cheers,
    dominick

    Reply
  2. Kenny

    Yes, we do run on IO completion threads by default. And I’m not recommending that you should just call QueueUserWorkItem to get off of the WCF dispatch thread. However, if your work is naturally async (and a Begin/End set of APIs should only be exposed if the API is directly or indirectly using I/O), then you will benefit from using the WCF async pattern. You can calculate pi in a synchronous operation, even if it takes a long time. But if you are holding an idle thread (i.e. calling Thread.Sleep, or out to a database, etc) then you want to let the system reuse the thread that you’re on. It’s possible that the thread you release will get recycled into the thread that completes your async operation, or maybe not. But either way you want to be concious of system resources and playing nice with the.

    Reply
  3. Pingback: WCF and the AsyncPattern (part 2) « Pedro Félix’s shared memory

  4. Pingback: WCF and the AsyncPattern property (part 2) « Pedro Félix’s shared memory

  5. Boaz

    There is something about Async operations I’m unclear about:

    Consider this working scenario:
    1. I don’t implement asynchronous service operations in the WCF service.
    2. I call service operations asynchronously from the client using AsyncPattern=true.
    3. I set InstanceContextMode.PerCall

    Does this guarantee me multi threaded parallel operations on the server?
    And also, with InstanceContextMode.PerCall, what happens after MaxConcurrentCalls have been reached. Are requests queued?

    Thanks,
    Boaz.

    Reply

Leave a Reply

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