简体   繁体   中英

Is this a correct diagram of how async-await works?

I'm going to be trying to give a talk on async - await and I'm creating a flow chart that attempts to show the possible orders of execution.

在此处输入图片说明

I attempted to base that off the paragraphs

The beginning of an async method is executed just like any other method. That is, it runs synchronously until it hits an “await” (or throws an exception).

The “await” keyword is where things can get asynchronous. Await is like a unary operator: it takes a single argument, an awaitable (an “awaitable” is an asynchronous operation). Await examines that awaitable to see if it has already completed; if the awaitable has already completed, then the method just continues running (synchronously, just like a regular method).

If “await” sees that the awaitable has not completed, then it acts asynchronously. It tells the awaitable to run the remainder of the method when it completes, and then returns from the async method.

Later on, when the awaitable completes, it will execute the remainder of the async method. If you're awaiting a built-in awaitable (such as a task), then the remainder of the async method will execute on a “context” that was captured before the “await” returned.

from http://blog.stephencleary.com/2012/02/async-and-await.html

The answer of usr is basically correct, though I think it makes too strong an analogy between threads and tasks. A task need not be anything like another thread. Remember, threads are workers, tasks are jobs. You can have a hundred things on your to-do list without hiring any workers to do them. Try to not think of tasks as lightweight workers, because they are not. They are jobs that need to be done; what worker does them is up to the code that handed you the task.

Your diagram starts off fine but it goes off the rails at "does the caller finish all independent work?" The continuation of the caller is, well, whatever it is. If that continuation involves doing work, it does work. Some of that work might be scheduling tasks to run on the current thread. Some of that work might be keeping the UI responsive.

Also, don't forget that the caller's thread could be terminated and the continuation of the task could be scheduled to another thread.

There are many, many things that can happen here; without understanding what exactly the caller is doing and what the thread context of the caller is, it is impossible to say what happens immediately after the await returns.

This

在此处输入图片说明

is vague and seems not correct.

What happens next inside the async method is not dependent on the caller. The method now is an independent agent (like a thread) that runs on its own. It has returned a Task that is a handle to itself. The caller can do with that task as he pleases (eg wait for it, await it, ...).

But if the caller simply drops that Task, the async methods keeps running.

The "re-enter" part of your picture happens at a time controlled by the awaited awaitable. Often, this is some external event such as a completed IO or a timer. The async method now resumes execution not knowing or caring who re-activated it.

Think of each async method as an independent thread. Each await logically is a Thread.Join() .

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