Hello, I wanted to try out such a tasty C # as async/await and wrote a test program:
class MySynchronizationContext : SynchronizationContext { public override void Post(SendOrPostCallback d, object state) { Console.WriteLine("Post"); base.Post(d, state); } public override void Send(SendOrPostCallback d, object state) { Console.WriteLine("Send"); base.Send(d, state); } } public class Program { public static void Main(string[] args) { SynchronizationContext.SetSynchronizationContext(new MySynchronizationContext()); var browsers = GetBrowsers(); Console.WriteLine("start"); Console.WriteLine(browsers.Result); } static async Task<string> GetBrowsers() { var res = string.Empty; var bd = await GetFromFS(); res += bd; // <-тут могла быть операция с UI var net = await GetFromNet(); res += " and " + net; // <-тут могла быть операция с UI var cpu = await Task.Run<string>(() => { Thread.Sleep(200); return "edge"; }); res += " and " + cpu; // <-тут могла быть операция с UI return res; } static async Task<string> GetFromFS() { using (var sr = new StreamReader(@"C:\bd.txt")) { var res = await sr.ReadToEndAsync(); // тут могла быть операция с UI return res + " and firefox"; } } static async Task<string> GetFromNet() { await Task.Delay(200); // тут могла быть операция с UI return "chrome"; } } I expected that after each await'а my context will be restored (after all, if this application is with the UI, then you need to access the controls), which means that after each await'а , “Post” will be displayed in the console, but what was My surprise when I got only 2 times. Hence the question:
- why the context is not always attached?
Now to async/await : as I understand it, starting with var browsers = GetBrowsers(); the call will be made on the stack down to the first task (in this case, sr.ReadToEndAsync(); or maybe lower), and the control will immediately go back to the Main() method, without waiting for the task to complete; the rest of the async methods will be executed after the execution of this task, and so on, from which the following question arises:
- Who is waiting for the very first task (then the next one, when will the queue come after
await'а), change its state toRanToCompletion? I think it would be foolish to think that a thread from the thread pool is allocated for waiting, right?
The third question is at the junction of task and thread pool. The continuation after await , as I understand it, is performed in the thread pool (the context is passed to it), but ...
- What puts a part of the code after
awaitinto the thread pool and when (when did the task complete or when it was created?)?
Thanks in advance for clarifying the situation