My question as the title suggest is about the background of 'async' and 'await'.
Is it true to say that what the current thread reaches 'await' keyword, it goes to "sleep", and wakes up when the await method is done?
Thanks!
Guy
My question as the title suggest is about the background of 'async' and 'await'.
Is it true to say that what the current thread reaches 'await' keyword, it goes to "sleep", and wakes up when the await method is done?
Thanks!
Guy
Is it true to say that what the current thread reaches 'await' keyword, it goes to "sleep", and wakes up when the await method is done?
No. The whole point of async
is to avoid having threads sleeping when they could be doing other work. Additionally, if the thread running the async method is a UI thread, you really don't want it to be sleeping at all - you want it to be available to other events.
When execution reaches an await
expression, the generated code will check whether the thing you're awaiting is already available. If it is, you can use it and keep going. Otherwise, it will add a continuation to the "awaitable" part, and return immediately.
The continuation makes sure that the rest of the async method gets run when the awaitable value is ready. Which thread that happens in depends on the context in which you're awaiting - if the async method is running in thread pool threads, the continuation could run on a different thread to the one the method started on... but that shouldn't matter. (The rest of the context will still be propagated.)
Note that it's fine for the async method to return without having completed - because an async method can't return a value directly - it always returns a Task<T>
(or Task
, or void
)... and the task returned by the method will be only be completed when the async method has really reached the end.
An await expression does not block the thread on which it is executing. Instead, it causes the compiler to sign up the rest of the async method as a continuation on the awaited task. Control then returns to the caller of the async method. When the task completes, it invokes its continuation, and execution of the async method resumes where it left off.
–
Poulin async
is only syntactic sugar that allows await
keyword to be used.
If async, await
is used in ASP.NET Core, then your request thread will be released to thread pool.
Asynchronous request handlers operate differently. When a request comes in, ASP.NET takes one of its thread pool threads and assigns it to that request. This time the request handler will call that external resource asynchronously. This returns the request thread to the thread pool until the call to the external resource returns. Figure 3 illustrates the thread pool with two threads while the request is asynchronously waiting for the external resource.
The important difference is that the request thread has been returned to the thread pool while the asynchronous call is in progress. While the thread is in the thread pool, it’s no longer associated with that request. This time, when the external resource call returns, ASP.NET takes one of its thread pool threads and reassigns it to that request. That thread continues processing the request. When the request is completed, that thread is again returned to the thread pool. Note that with synchronous handlers, the same thread is used for the lifetime of the request; with asynchronous handlers, in contrast, different threads may be assigned to the same request (at different times).
For desktop application:
await
releases the current thread, but NOT to the thread pool. The UI thread doesn't come from the thread pool. If you run asynchronous method, e.g.ExecuteScalarAsync
withoutasync, await
keywords, then this method will run asynchronously no matter what. The calling thread won't be affected .Special thanks for nice comments to Panagiotis Kanavos.
E.g. you have a heavy stored procedure and your stored procedure takes 10 minutes to be executed. And if you run this code from C# without async, await
keywords, then your execution thread will wait your stored procedure for 10 minutes. And this waiting thread will do nothing, it will just wait stored procedure.
However, if async, await
keyword is used, then your thread will not wait stored procedure. The thread will be eligible to work.
Although this question has already been answered by Jon Skeet who is a highly skilled person (and one of my favorites), it is worth reading the contents that I mention below for other readers of this post.
By using an async
keyword on a method, the original asynchronous method creates a state machine instance, initializes it with the captured state (including this
pointer if the method is not static), and then starts the execution by calling AsyncTaskMethodBuilder<T>.Start
with the state machine instance passed by reference.
As soon as control reaches an await
keyword, the current thread (which can be a .Net thread pool's worker thread), creates a callback (as a delegate
) to execute the rest of the sync code exactly after the await
keyword (Continuation) using the SynchronizationContext/TaskSheduler's APIs (SynchronizationContext
may not be present in all applications, such as Console Applications or ASP.Net Core Web Applications), the captured SynchronizationContext
is stored in the state machine as an object, the IO work is sent to an IOCP thread, and the current thread is then released.
The IOCP thread binds to an IOCP (IO Completion Port), opens a connection, and asks it to execute the code that has been waited, and the IOCP sends the execution command to the corresponding device (socket/drive).
Whenever the IO work is finished by the relevant device, a signal from the IOCP is returned to the IOCP thread along with the result of the IO work, and then the IOCP thread, based on that captured SynchronizationContext
determines which thread of thread pool should process the continuation/callback (that was stored in the state machine).
Also, the following articles can be useful:
No. Current thread actually doesn't go to sleep. The execution continues. This is the whole trick of it. You may have some code that processes data while asynchronous actions are still pending. It means that by the time those async completes your main thread is free to run and process other data.
As for the other part of the question - async just executes on another thread, not the current one. I believe that CLR is responsible for spinning those threads, so that many async actions are allowed at the same time (i.e. you may be retrieving data asynchronously from different web servers at the same time).
© 2022 - 2024 — McMap. All rights reserved.
async await
. Indeed, you get this: msdn.microsoft.com/en-us/library/hh156528.aspx. – Poulinawaiting
thread in C# Async CTP? – Exodontics