Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

async await and threading

Tags:

c#

async-await

based on what I have read on MSDN

The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active. You can use Task.Run to move CPU-bound work to a background thread, but a background thread doesn't help with a process that's just waiting for results to become available.

It is basically saying no thread will be created. But inside a class which I inherited HttpClient I found something interesting..

async Task<T> SendAsync<T>(HttpMethod method, Uri uri, HttpContent content, CancellationToken cancellationToken) 
{
        HttpRequestMessage msg = new HttpRequestMessage(method, uri); 
        msg.Content = content;
        //On Main Thread
        HttpResponseMessage response = await SendAsync(msg, cancellationToken);
        //On worker thread
        //...
}

the method is called inside static void Main

Task result = client.GetAsync<string>(...);
//GetAsync calls await SendAsync<T>
result.Wait();

Why am I on a separate thread after await SendAsnc call?? I thought asyn creats no new thread. Or at least it will be invoked back to the original thread after await.

like image 476
Steve Avatar asked Oct 25 '16 20:10

Steve


People also ask

Is async await a thread?

An await expression in an async method doesn't block the current thread while the awaited task is running. Instead, the expression signs up the rest of the method as a continuation and returns control to the caller of the async method. The async and await keywords don't cause additional threads to be created.

Is async same as threading?

It is a general misconception that both asynchronous programming and multithreading are the same although that's not true. Asynchronous programming is about the asynchronous sequence of Tasks, while multithreading is about multiple threads running in parallel.

Is async better than threading?

Asyncio vs threading: Async runs one block of code at a time while threading just one line of code at a time. With async, we have better control of when the execution is given to other block of code but we have to release the execution ourselves.

Is async faster than multithreading?

So why asyncio is faster than multi-threading if they both belong to asynchronous programming? It's because asyncio is more robust with task scheduling and provides the user with full control of code execution.


2 Answers

This is poorly advertised in the documentation, but the way that async/await works in a console application is very different than how it works in a UI application due to the lack of a synchronization context in a console application. This article describes details and gives a code sample of how add one so that async/await behaves in a more predictable way.

Normally, you're absolutely correct about async/await not necessarily entailing multithreading (although things like Task.Run do, in fact, cause the code in question to run in the thread pool), but (as described in the article I linked to) in a console application async/await could run anywhere.

My usual analogy for how async works when running on the same thread is to think of going to a restaurant with 9 other people (so 10 people total). When the waiter comes by, 9 of the people are ready and the 10th isn't. In this case, the waiter will take the other 9 people's orders first and then come back to the 10th person. If for whatever reason the 10th person's being really slow the waiter could always bring the orders back to the kitchen and come back when the 10th person's ready.

Clearly, there's no point to bringing in a second waiter just to wait for the 10th guy to be ready to order, and it would clearly be inefficient to make everyone else wait for the one guy to be ready. Adding extra waiters to the situation won't speed things up because the delay isn't being caused by a lack of waiters, it's caused by the 10th guy being slow to make up his mind (and there's nothing the wait staff can do about that).

like image 58
EJoshuaS - Stand with Ukraine Avatar answered Oct 22 '22 19:10

EJoshuaS - Stand with Ukraine


I describe this behavior in my introduction to async blog post.

In summary, this is correct:

The async and await keywords don't cause additional threads to be created.

And so is this:

I thought asyn creats no new thread.

This is not correct:

Or at least it will be invoked back to the original thread after await.

async and await - by themselves - do not cause any additional threads to be created. However, after an await completes, the remainder of the async method must run somewhere.

By default, await captures a "context", which is the current SynchronizationContext (unless it is null, in which case the current context is the current TaskScheduler). UI threads have their own synchronization context (e.g., WinFormsSynchronizationContext or DispatcherSynchronizationContext), and in that case, the async method will continue executing on that same UI thread.

In a Console application, there is no synchronization context, so the "context" captured by await will be the thread pool context. Thus, when the async method is ready to resume, it will be scheduled to the thread pool and picked up by some thread there.

like image 26
Stephen Cleary Avatar answered Oct 22 '22 19:10

Stephen Cleary