Is the above steps sequence correct?
No.
The correct sequence is
- MyMethod calls Method1.
- Method1 does the code before the call to Method2.
- Method1 calls Method2.
- Method2 does the code before the call to LongRunMethod.
- Method2 calls LongRunMethod.
- LongRunMethod returns a task to Method2.
- Method2 interrogates the task to see if it is complete. Let's suppose it is not.
- Method2 signs up "do no additional work, and then mark method2's task as complete" as the continuation of the task just returned, and returns its task to Method1.
- Method1 interrogates the task just returned from method2. Let's suppose it's not complete. It assigns the work that happens after the await as the continuation of method1's task, and returns that task to its caller.
- MyMethod interrogates the task just returned from Method1. Let's suppose it's not complete. It signs up the remainder of that work to the continuation of its task, and returns that task to its caller.
- That caller, whatever it is, does whatever work it does.
- At some point in the future, LongRunMethod's task completes asynchronously and requests that its continuation be resumed in the appropriate context.
- Eventually that context gets to run code, and it runs the continuation of the LongRunMethod task, which is, recall, to do no work and then mark the Method2 task as complete.
- It does so. Method2's task is now complete, so it requests its continuation to run on the appropriate context.
- Eventually that runs. Recall that Method2 task's continuation is to run the remainder of Method1. It does so, and then marks Method1's task as complete. That requests that Method1's task run its continuation.
- Eventually that continuation runs. Its continuation is to call Task.Delay.
- Task.Delay returns a task. MyMethod interrogates the task. It's not complete. So it signs up "go back to the top of the loop" as the continuation of that task. It then returns.
- Whatever code triggered the continuation of LongRunMethod's task keeps doing work. At some point ten seconds in the future the delay task completes and requests that its continuation executes.
- Eventually the continuation executes on the appropriate context. The continuation is "go back to the top of the loop", and the whole thing starts over.
Note that the task returned by MyMethod never completes normally; if any of those tasks throw exceptions then it completes exceptionally. For simplicity I've ignored the checks for exceptional continuation in your example, since there is no exception handling.
What methods do get control after Method1() and Method2() finish their work?
The remainder of Method1 eventually gets control after the task returned by Method2 is completed. MyMethod eventually gets control after the task returned by Method1 is completed. The exact details of when the continuations are scheduled depends on the context in which the code is running; if they're on the UI thread of a form, that's very different than if they're in worker threads on a web server.
What is going to happen if LongRunMethod() runs longer than 10000ms?
I think you mean what happens if the task returned by LongRunMethod does not complete for more than ten seconds. Nothing particularly interesting happens then. The delay is not started until after LongRunMethod's task is done. You awaited that task.
I think you fundamentally do not understand what "await" means. You seem to think that "await" means "start up this code asynchronously", but that is not at all what it means. The code is already asynchronous by assumption. Await manages asynchrony; it does not create it.
Rather, await is an operator on tasks, and it means if this task is complete then keep going; if this task is not complete then sign up the remainder of this method as the continuation of that task and try to find some other work to do on this thread by returning to your caller.
No code that is after an await executes before the awaited task is completed; await means asynchronously wait for the completion of the task. It does NOT mean "start this code asynchronously". Await is for declaring what points in an asynchronous workflow must wait for a task to finish before the workflow can continue. That's why it has "wait" in the name.