Say we have the following program
public class Program
{
public static async Task Main(string[] args)
{
var x = 5;
var y = await FooAsync();
var z = x + y;
}
public static async Task<int> FooAsync()
{
var p = "foo";
await Task.Delay(100);
return p.GetHashCode();
}
}
After the "true async work" launched from Task.Delay is initiated, there exists a call stack like
---------------------------------
...
---------------------------------
p: "foo"
return value: (unset)
---------------------------------
continueOnCapturedContext: true
x: 5
y: (unset)
z: (unset)
return value: (none)
---------------------------------
and some sort of pointer to
---> await Task.Delay(100);
so that when this async work completes (via some interrupt), execution can continue where it left off.
A few questions:
- Where is this call stack, in terms of a .NET type I can experiment with in Visual Studio?
- My understanding is that the thread which executes this "remainder" could be any thread. So let's say there are only threads A, B, C when the program launches and say A ran up until the async work began. I know A is then considered "done" and returns to some zero state (
ThreadState.Stopped?ThreadState.Unstarted?) so that it could be used for more work if there was more. How does the thread which is chosen to execute the raminer, which could be any of A, B or C, get associated with the call stack? I don't see any constructors forThreadwhich give it this info.