简体   繁体   中英

What happens to the thread when reaching 'await' on 'async' method?

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.

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 (ie you may be retrieving data asynchronously from different web servers at the same time).

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.

As Stephen Cleary says:

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, eg ExecuteScalarAsync without async, 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 .

Eg 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM