3

After reading alot about async-await, I can only find the benefits of using it in GUI thread (WPF/WinForms).

In what scenarios does it reduce the creation of threads in WCF services? Does a programmer must use async-await on every method in the service by choosing to implement async-await in web service? Making some non-async-await methods in a service full of async-await reduse the efficiency of my service? How?

Last question - some say that using 'await Task.Run(()=>...)' is not a "real async-await". What do they mean by saying that?

Thanks in advence, Stav.

EDIT:

Both answers are excellent but for even dipper explanation about how async-await works, I suggest to read @Stephen Cleary answer here: https://stackoverflow.com/a/7663734/806963

Following topics are required for understand his answer: SynchronizationContext,SynchronizationContext.Current,TaskScheduler,TaskScheduler.Current,Threadpool.

Community
  • 1
  • 1
Stav Alfi
  • 13,139
  • 23
  • 99
  • 171
  • 2
    `Task.Run` is used to execute cpu-bound code on a threadpool thread. The real async-await is about IO-bound code. – Andrey Nasonov Oct 08 '15 at 23:07
  • 1
    The question might indeed seem too broad, but considering the correct answer, IT IS NOT. The whole concept can be fully and clearly explained in 5 paragraphs. – Jakub Lortz Oct 09 '15 at 00:51

2 Answers2

5

The real benefit of async/await in server applications (like WCF) is asynchronous I/O.

When you call a synchronous I/O method, the calling thread will be blocked waiting for the I/O to complete. The thread cannot be used by other requests, it just waits for the result. When more requests arrive, the thread pool will create more threads to handle them, wasting a lot of resources - memory, context switching when the waiting threads get unblocked...

If you use async IO, the thread is not blocked. After starting the asynchronous IO operation, it is again available to be used by the thread pool. When the async operation is finished, the thread pool assigns a thread to continue processing the request. No resources wasted.

From MSDN (it's about file I/O, but applies to other too)

In synchronous file I/O, a thread starts an I/O operation and immediately enters a wait state until the I/O request has completed. A thread performing asynchronous file I/O sends an I/O request to the kernel by calling an appropriate function. If the request is accepted by the kernel, the calling thread continues processing another job until the kernel signals to the thread that the I/O operation is complete. It then interrupts its current job and processes the data from the I/O operation as necessary.

Now you probably can see why await Task.Run() will not give any benefit if the IO in the task is done synchronously. A thread will get blocked anyway, just not the one that called the Task.Run().

You don't need to implement every method asynchronously to see improvement in performance (although it should become a habit to always perform I/O asynchronously).

Jakub Lortz
  • 14,616
  • 3
  • 25
  • 39
  • I admit I thought every call get a new thread not from threadpull. this was very helpfull. Although the logic tell me that if I create a method (method1) that return a task for other method to async it (call: await method1()) it is the same as doing await Task.Run(method1()) becouse method1 implement return Task.run(()=>());. So I dont have any benefits for avoiding it. Am I currect? – Stav Alfi Oct 08 '15 at 23:59
  • 1
    You are correct. To correctly implement async IO without using existing async methods in .NET BCL you would have to work on much lower level, very close to the OS. Fortunately, everything is nicely handled by the .NET BCL, so you can just await these methods. – Jakub Lortz Oct 09 '15 at 00:12
0

In what scenarios does it reduce the creation of threads in WCF services?

If you have an action that will wait on an IO operation (reading from the database, calling an external web service, ...), using async/await frees up the managed thread that your WCF request is being processed on. That makes the thread available for other requests, pending completion of your IO. It makes for more efficient use of the thread pool.

After reading alot about async-await, I can only find the benefits of using it in GUI thread

For client applications that is the key benefit that I'm aware of, since you are far less likely to run out of manged threads than you are in a server application.

some say that using 'await Task.Run(()=>...)' is not a "real async-await".

You allocate a new managed thread to run your new task, so you are not saving any managed threads.

Eric J.
  • 147,927
  • 63
  • 340
  • 553
  • If I understand, WCF use thread-pull to handle any requests + any async-await opertions? so If i implement my own async-await by returning new task - it doesnt really create one, only use some thread-pull thread instead? – Stav Alfi Oct 09 '15 at 00:04
  • HTTP requests are handled by the thread pool. IO operations do not require a thread while they are pending. – Eric J. Oct 09 '15 at 00:18
  • So what you tell me is Async-IO opertion is not on other thread? its a blocking opertion anyway? – Stav Alfi Oct 09 '15 at 00:32
  • @StavAlfi Check https://msdn.microsoft.com/en-us/library/windows/desktop/aa365683(v=vs.85).aspx It seems old. but the information is still valid. – Jakub Lortz Oct 09 '15 at 00:44
  • Thnanks you 2 were very helpfull. – Stav Alfi Oct 09 '15 at 00:59