Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected behaviour after returning from await

I know there are a lot of questions about async/await, but I couldn't find any answer to this.

I've encountered something I don't understand, consider the following code:

void Main()
{
    Poetry();
    while (true)
    {
        Console.WriteLine("Outside, within Main.");
        Thread.Sleep(200);
    }
}

async void Poetry()
{
   //.. stuff happens before await
   await Task.Delay(10);
   for (int i = 0; i < 10; i++)
   {
       Console.WriteLine("Inside, after await.");
       Thread.Sleep(200);
   }
}

Obviously, on the await operator, the control returns to the caller, while the method being awaited, is running on the background. (assume an IO operation)

But after the control comes back to the await operator, the execution becomes parallel, instead of (my expectation) remaining single-threaded.

I'd expect that after "Delay" has been finished the thread will be forced back into the Poetry method, continues from where it left.

Which it does. The weird thing for me, is why the "Main" method keeps running? is that one thread jumping from one to the other? or are there two parallel threads?

Isn't it a thread-safety problem, once again?

I find this confusing. I'm not an expert. Thanks.

like image 921
Letterman Avatar asked Dec 07 '13 19:12

Letterman


1 Answers

I have a description on my blog of how async methods resume after an await. In essence, await captures the current SynchronizationContext unless it is null in which case it captures the current TaskScheduler. That "context" is then used to schedule the remainder of the method.

Since you're executing a Console app, there is no SynchronizationContext, and the default TaskScheduler is captured to execute the remainder of the async method. That context queues the async method to the thread pool. It is not possible to return to the main thread of a Console app unless you actually give it a main loop with a SynchronizationContext (or TaskScheduler) that queues to that main loop.

like image 114
Stephen Cleary Avatar answered Nov 15 '22 03:11

Stephen Cleary