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.
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.
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.
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.
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.
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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With