4

I am creating a RESTful web service using WCF. Consider the Service contract and implementation below:

[ServiceContract]
    public interface IItemsSaleService
    {
        [OperationContract]
        [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "getItemDetails/{itemId}")]
        SaleItem GetItemDetails(string itemId); //GET
}

//IMPLEMENTATION

async public SaleItem GetItemDetails(string itemId) //This wont work. It should be Task<SaleItem>
        {

            SaleItem item = await FindItem(itemId);
            return item;
        }

Assume that the FindItem is a thirdparty API method. Since I am using await, the method GetItemDetails has to be marked async and hence cannot return SaleItem. It has to return void or a Task which wont work for me as the method HAS to return SaleItem for the serializer to convert it to JSON and return it back to the client.

How do I fix this?

Another related question:

Method A calls Method B calls Method C - Method C uses await. Does this automatically require all the other methods to be async and hence always return Task<> or void?

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
bobbyalex
  • 2,681
  • 3
  • 30
  • 51
  • 2
    You can make the `GetItemDetails` method `async` and return `Task` from it. WCF will understand this form of the contract: http://stackoverflow.com/q/22623922/1768303 – noseratio Jun 11 '14 at 09:11
  • @Noseratio: If this is the case, how will the caller behave? For eg: if I were to call GetItemDetails from an iOS app, will the call (in iOS) wait till I get a response? If so, who does this? I mean turn the async call to sync? – bobbyalex Jun 11 '14 at 09:32
  • 1
    Asynchrony on the client is totally independent from asynchrony on the server. The client won't receive the response from the server, until the request has been fully processed by the server (either synchronously or asynchronously). For more details, check this: http://stackoverflow.com/q/22638828/1768303. – noseratio Jun 11 '14 at 09:41

1 Answers1

4

Assume that the FindItem is a thirdparty API method. Since I am using await, the method GetItemDetails has to be marked async and hence cannot return SaleItem. It has to return void or a Task which wont work for me as the method HAS to return SaleItem for the serializer to convert it to JSON and return it back to the client.

It WILL work. From MSDN:

Clients can offer the developer any programming model they choose, so long as the underlying message exchange pattern is observed. So, too, can services implement operations in any manner, so long as the specified message pattern is observed.

This means that WCF can switch between synchronous and asynchronous patterns for a single message. An extensive answer is provided in Noseratios link: Different forms of the WCF service contract interface

Method A calls Method B calls Method C - Method C uses await. Does this automatically require all the other methods to be async and hence always return Task<> or void?

Async methods by nature propogate all the way up. A method which uses the await keyword will have to mark its method async and have a return type of either Task, Task<T>, or void. Notice a void returning async method is ment solely for the compatability of async event handlers, and shouldn't be used outside of that scope.

There are cases when making your method async isn't necassery, and simply returning the inner called Task will suffice, you can read more about it here: Any difference between "await Task.Run(); return;" and "return Task.Run()"?

Community
  • 1
  • 1
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321