If you compile the following code:
private async Task<int> M()
{
return await Task.FromResult(0);
}
And then decompile it (I used dotPeek) and examine the all-important MoveNext
method, you will see a bool
variable declared near the beginning; dotPeek chose "flag" for me.
bool flag = true;
In this case, you will see one subsequent consumer of that variable, in the default case statement after initiating the first async call:
if (!awaiter.IsCompleted)
{
this.\u003C\u003E1__state = 0;
this.\u003C\u003Eu__\u0024awaiter11 = awaiter;
this.\u003C\u003Et__builder.AwaitUnsafeOnCompleted<TaskAwaiter<int>, Program.\u003CP\u003Ed__10>(ref awaiter, ref this);
flag = false;
return;
}
I've tried half a dozen more complicated examples than my initial one, and they are consistent in only assigning to this variable before exiting the method. So in other words, in all the cases I've tried so far, this variable is not only never consumed, but is only given a non-initial value immediately before returning from the method -- a point in time where the assignment is definitionally useless.
As background, I am enjoying the process of trying to implement async/await in Javascript via a C# -> JS cross-compiler. I'm trying to understand in what situation I need to consider the utility of this flag. At face, it seems spurious and therefore I should ignore it. However, I'd like to understand why the C# compiler introduces this variable -- I suspect there are more complicated expressions that consume this variable in a useful way.
To put is succinctly: Why does the C# compiler generate this flag
variable?