简体   繁体   中英

If async/await doesn't create new thread then explain this code

I've read this thread which claims with reference to msdn with idea that async/await doesn't create new threads. Please look at following code:

static class Program
{
    static void Main(string[] args)
    {
        var task = SlowThreadAsync();
        for(int i = 0; i < 5; i++)
        {
            Console.WriteLine(i * i);
        }
        Console.WriteLine("Slow thread result {0}", task.Result);
        Console.WriteLine("Main finished on thread {0}", Thread.CurrentThread.ManagedThreadId);
        Console.ReadKey();
    }

    static async Task<int> SlowThreadAsync()
    {
        Console.WriteLine("SlowThreadAsync started on thread {0}", Thread.CurrentThread.ManagedThreadId);
        await Task.Delay(2000);
        Console.WriteLine("SlowThreadAsync completed on thread {0}", Thread.CurrentThread.ManagedThreadId);
        return 3443;

    }
}

As result of this code I got different ThreadId. Why the same thread gets different ThreadId?

不同的线程

You're using a console application for your example. This effects greatly the outcome of your test. A console application has no custom SynchronizationContext (like Winforms, WPF and ASP.NET have), hence it uses the ThreadPoolTaskScheduler to schedule continuations on an arbitrary thread-pool thread. Try this same example in a UI application and you'll see the continuation invoked on the same thread.

What the articles you linked are trying to get across is that calling async methods does not guarantee that any of the code runs on a separate thread. So if you do want to guarantee this, you have to do it manually. In particular they're not trying to say that an async method will always run on the same thread as the calling method , because this is blatantly false in many scenarios.

I know its been a bit since the question was asked, but I ran into this problem and have come up with more details on why/when this happens. await works by scheduling the code following the await to be run after the awaited task finishes, on whatever thread the threadpool finds convenient. Oftentimes this seems to be on the same thread as the awaited task. Not sure how this plays with SynchronizationContext mentioned in other answers.

I have noticed an exception is when the awaited task finished quickly, it seems like their isn't enough time to place the code on the callback, so the code ends up being called on a third thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM