4

I have few async way of writing program questions. I am writing WCF service with some expensive methods, which are good candidates for async calling. But my questions about the implementations are:

  1. If I will create async method in the model, then I need mark service method as async to be able to await the model method, and change the return type to Task<originalType>. This will destroy service API convention consistency. What is the right way to go? Is it better to design the service interface as async Task returning methods even if some methods are not expensive and there is practically no reason to make it async?
  2. As I understood, only expensive method should be written as async, but in such case one half of the program will bee synchronous and the second one asynchronous. Is it right?
i3arnon
  • 113,022
  • 33
  • 324
  • 344
Fanda
  • 3,760
  • 5
  • 37
  • 56

3 Answers3

5

I wouldn't say you need async-await when there's an "expensive" method. A better guideline is to use async-await when there are truly asynchronous operations (which are mostly IO calls).

If you have many of those operations it would be a waste holding a thread throughout their runtime, and it can heavily hinder scalability. It's a tradeoff and you need to decide for yourself what's more important to you: simplicity or scalability.

If your application is a rich client, maybe scalability isn't that important, but in a WCF service I would always choose the asynchronous option if I can.

i3arnon
  • 113,022
  • 33
  • 324
  • 344
  • 1
    In a GUI application, you don't want to block the UI thread for long running synchronous (e.g. CPU-bound) operations, so it makes sense to use something like `await Task.Run()` there. But the same doesn't apply for WCF services or the like. – svick Jun 24 '14 at 16:55
  • 1
    @svick Indeed. `async-await` in WCF Services is all about scalability while in GUI apps it's about offloading. – i3arnon Jun 24 '14 at 17:04
5

If I will create async method in the model, then I need mark service method as async to be able to await the model method, and change the return type to Task. This will destroy service api convention consistency. What is the right way to go? Is it better to design the service interface as async Task returning methods even if some methods are not expensive and there is practically no reason to make it asnyc?

In WCF, when you change your method to return a Task<T>, you're actually not changing the WCF contract, as it can identify multiple asynchronous pattern for a single message, which means you can have all 3 patterns (Task, Sync and APM) in a single contract interface, and they would all relate to the same message.

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 subject is covered to extend in Different forms of the WCF service contract interface and Asynchronously consume synchronous WCF service

As I understood, only expensive method should be written as async, but in such case one half of the program will bee synchronous and the second one asynchronous. Is it right?

As @l3arnon said, exposing an async api is not about how "expensive" the method is, it is about the work the method call is doing. if its true asynchronous work, such as accessing the file system, sending a network request, accessing an external data source, such as a database, then that is a fit candidate to expose an async api.

Combining these facts with WCF, you can expose both sync and async method via a single contract.

Community
  • 1
  • 1
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
  • Selected as answer for best matching with the question. But all answers are very useful. Thank you guys. – Fanda Jun 25 '14 at 05:58
2
  1. Whether you chose to make your service methods sync or async cannot be detected by the caller. The contract does not change. Task and IAsyncResult are not serializable over SOAP anyway so it cannot possibly be the case that a Task is transmitted to the client. I have explained this extensively before.
  2. Not "expensive", but long-running IO-bound. The gain of async on the server is to save a thread from being blocked. This temporarily saves 1MB of stack space and one thread-pool slot. If you do not need this gain, and most workloads do not, don't go async. Going async is not free from a development point of view.
Community
  • 1
  • 1
usr
  • 168,620
  • 35
  • 240
  • 369