I am quite confused with the subject. I am coming from assumption that task creation and its scheduling should be strictly separated which seams not to be the case in C#.
Consider the following simple code.
static async Task simpleton()
{
print("simpleton");
}
static async Task cont()
{
print("cont");
}
static void Main(string[] args)
{
Task t1 = simpleton();
Task t2 = t1.ContinueWith((a) => { cont(); });
Thread.Sleep(1000);
return;
}
The output is
simpleton
cont
simpleton function runs and creates the task t1 (already completed) - that's ok. However the t2 seams to be (at least in code) only task creation - no scheduling was asked from the system, so why and who's schedules the continuation to run? Clearly the creation/running principle is broken here.
Similar situation is with await. Consider the pseudo code in this very well known article. According to pseudo code await is translated into the continuation task and returned to the caller, which I would expect must schedule the task in order to complete it . Also this is not the case, consider the following code:-
static async Task foo()
{
await bar();
}
static async Task bar()
{
print("bar");
}
static void Main(string[] args)
{
foo();
Thread.Sleep(1000);
return;
}
bar will be executed without specifically scheduling the Task object created by foo.
So the questions are:
Is it correct that ContinueWith not only creates the task but also schedules it .
Is it correct that await not only creates the task for continuation as appears in the article but also schedule if possible (Call Post on SynchronizationContext or TaskScheduler).
Why this design (scheduling and creation mixed) was adopted by async/await language designers?