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 forThread
which give it this info.