Royi Namir
Royi Namir

Reputation: 148744

async ( with non-async) function control flow clarification?

( I've read a lot about async and I wonder what happens if there is a mix of async function call and non-async) and im talking about THREAD pov .

( I know that mix should not be done , but im asking in order to understand the flow better)

suppose I have(cube 1) function which calls async functions which calls asyc function.

(please notice that cube 1 function is not async)

Question : when the control reaches (cube 3) await Task.Delay(100); --

what is really happening as the control reaches cube3 await ? does the control is back(and blocked) at the pink arrow (cube 1 ) or does the control is released and still awaits ( orange arrow)

enter image description here

Upvotes: 2

Views: 234

Answers (1)

Frédéric Hamidi
Frédéric Hamidi

Reputation: 263147

When control reaches the await statement in Cube3, Task.Delay() is called and immediately returns a Task that will complete after the delay. The rest of CalculateAnswer() is refactored into a continuation that will run when the Task returned by Delay() completes, and CalculateAnswer() immediately returns a Task<int> that will complete when that continuation completes.

CallCalculateAnswer() awaits the Task<int> returned by CalculateAnswer(), so the same logic applies: the code running after the await (i.e. the return statement) is refactored into a continuation that will run when the Task<int> completes, and CallCalculateAnswer() proceeds to return its own Task<int>.

StartChain(), however, does not await the Task<int> produced by CallCalculateAnswer(), so no continuation is generated. Instead, it stores the task into a local variable and returns. Therefore, the orange arrow in your question is the right one.

Note that, in this specific case, since nothing is done with the Task<int> returned by CallCalculateAnswer() and it is only stored in a local variable, it becomes "forgotten" once StartChain() returns: the task will complete (or fail) some time in the future, but its result (the int it produces) will be lost.

Update following comments: The pink arrow in your question implies you're expecting StartChain() to block, waiting for the task returned by CallCalculateAnswer() to complete, because it is not async and does not await that task. This is not what happens, as the usual control flow semantics apply: the method has returned a task, so you get a reference to that task and nothing more.

If you want StartChain() to block, you can use Task.Wait(), Task<T>.Result, or similar on the task returned by CallCalculateAnswer().

Upvotes: 2

Related Questions