One-way async/await calls in WCF

.net, async-await, c#, wcf

Solution

First off, the client is entirely separate from the server. Either client or server may be synchronous, use `IAsyncResult` (APM) asynchronous code, or use `async` (TAP) asynchronous code.

Secondly, `async` methods on the server side should return `Task`, even for one-way communications. The `async` equivalent of a synchronous method returning `void` is an `async Task` method, not an `async void` method. `async void` is especially dangerous in WCF services since it may violate the `ConcurrencyMode`.

So your server-side steps would look like this:

- Remove `OperationContract.AsyncPattern`.

- Combine the `Begin*`/`End*` method pair into a single `*Async` method which returns `Task`.

Your client side should see `Task`-returning methods on the interface for its proxy, which it should `await`. This does not mean that you're waiting for a response; this `await` enables you to wait for the actual message to be sent (if there are delays) and detect channel communications errors (if you are using a reliable channel).

Problem

I have a legacy WCF service with a number of One-Way operation contracts implemented in the most classic way: ``` // The interface [OperationContract(IsOneWay = true, AsyncPattern = true)] IAsyncResult BeginFinalizePublishing(PageContent pageContent, AsyncCallback callback, object asyncState); void EndFinalizePublishing(IAsyncResult result); // The service public IAsyncResult BeginFinalizePublishing(PageContent pageContent, AsyncCallback callback, object asyncState) {...} ``` So everything works fine here, now I need to convert this to c# 5 latest async/await pattern. Pay attention to the one way nature of the operations. My questions: - I guess I need to remove the `AsyncPattern = true` from the `OperationContract` attribute. - Replace the `IAsyncResult` return type with the `void` in the interface and `async void` in the class. - Remove the Begin/End and add the Async postfix for the sake of convenience. Now how should I call the one-way operation from the client? No usage of async/await on the client-side right for one-way calls? Is this correct and will result in a true asynchronous processing on the client side. ``` // The proxy public void FinalizePublishingAsync(PageContent pageContent) { Channel.FinalizePublishingAsync(pageContent); } // The consumer of the client // No way to use await for void methods. IComPublisherFinalizerClient cl = new IComPublisherFinalizerClient(); cl.FinalizePublishingAsync(content); cl.Close(); ```

Original source