Answer the question
In order to leave comments, you need to log in
How do await chains work in C#?
Hello. Now I'm studying asynchrony in C # and decided to check the await call chains.
I read many times that if await encounters a Task that has not yet been executed, then the method returns an incomplete task and execution continues in the calling method.
Why, after the await Method2Async() line in the first example, control is not transferred to Main, but Method2Async begins to execute on the same thread?
And in the second example, when instead of await Method2Async() write await Task.Run(Method2Async) , the opposite is true. The result will be a different conclusion. I would be glad if someone tells more about how such chains work or threw off some source. Thanks in advance for your reply.
one:
static void Main(string[] args)
{
Console.WriteLine("MAIN BEFORE Method1Async THREAD ID : " + Thread.CurrentThread.ManagedThreadId);
Task method1Task = Method1Async();
Console.WriteLine("MAIN AFTER Method1Async THREAD ID : " + Thread.CurrentThread.ManagedThreadId);
Console.Read();
}
static async Task Method1Async()
{
Console.WriteLine("Starting Method1Async Thread id: "+ Thread.CurrentThread.ManagedThreadId);
await Method2Async(); // Меняется только эта строка
Console.WriteLine("End Method1Async Thread id: " + Thread.CurrentThread.ManagedThreadId);
}
static async Task Method2Async()
{
Thread.Sleep(100);
Console.WriteLine("Starting Method2Async Thread id: "+ Thread.CurrentThread.ManagedThreadId);
await Task.Run(() =>
{
Thread.Sleep(100);
Console.WriteLine("INNER TASK STARTED Thread id: " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(2000);
Console.WriteLine("INNER TASK ENDED Thread id: " + Thread.CurrentThread.ManagedThreadId);
});;
Console.WriteLine("End Method2Async Thread id: " + Thread.CurrentThread.ManagedThreadId);
}
static void Main(string[] args)
{
Console.WriteLine("MAIN BEFORE Method1Async THREAD ID : " + Thread.CurrentThread.ManagedThreadId);
Task method1Task = Method1Async();
Console.WriteLine("MAIN AFTER Method1Async THREAD ID : " + Thread.CurrentThread.ManagedThreadId);
Console.Read();
}
static async Task Method1Async()
{
Console.WriteLine("Starting Method1Async Thread id: "+ Thread.CurrentThread.ManagedThreadId);
await Task.Run(Method2Async); // Меняется только эта строка
Console.WriteLine("End Method1Async Thread id: " + Thread.CurrentThread.ManagedThreadId);
}
static async Task Method2Async()
{
Thread.Sleep(100);
Console.WriteLine("Starting Method2Async Thread id: "+ Thread.CurrentThread.ManagedThreadId);
await Task.Run(() =>
{
Thread.Sleep(100);
Console.WriteLine("INNER TASK STARTED Thread id: " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(2000);
Console.WriteLine("INNER TASK ENDED Thread id: " + Thread.CurrentThread.ManagedThreadId);
});;
Console.WriteLine("End Method2Async Thread id: " + Thread.CurrentThread.ManagedThreadId);
}
Answer the question
In order to leave comments, you need to log in
I have read many times that if await encounters a Task that has not yet been executed, then the method returns an incomplete task and execution continues in the calling method.
static async Task Method1Async()
{
Console.WriteLine("Starting Method1Async Thread id: "+ Thread.CurrentThread.ManagedThreadId);
var task = Method2Async();
await task; // До этой точки код выполняется синхронно (если таска ещё не готова)
Console.WriteLine("End Method1Async Thread id: " + Thread.CurrentThread.ManagedThreadId);
}
static async Task Method2Async()
{
Thread.Sleep(100); // Thread.Sleep - это блокирующая операция
Console.WriteLine("Starting Method2Async Thread id: "+ Thread.CurrentThread.ManagedThreadId);
await Task.Yield(); // До этой точки код выполняетя синхронно. Task.Yield освобождает поток всегда
Console.WriteLine("End Method2Async Thread id: " + Thread.CurrentThread.ManagedThreadId);
}
My friend, this is exactly the place where they ask if they haven’t found it, haven’t understood it, haven’t read it
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question