使用async / await时,在Task中的线程池线程上放了什么?

时间:2012-11-01 10:21:19

标签: c# multithreading threadpool

请考虑以下代码

    public static async Task<int> Answer()
    {
        await Task.Delay(1000);
        return 42;
    }

    static void Main(string[] args)
    {
        for (int j = 0; j < 20; j++)
        {
            Console.WriteLine(j +" " + Thread.CurrentThread.IsThreadPoolThread);
            if (j == 1)
            {
                new Task( async ()=>
                    {
                        int answer = await Answer();
                        Console.WriteLine(answer + " " + Thread.CurrentThread.IsThreadPoolThread);
                    }).Start();
            }

            Thread.Sleep(200);
        }

        return;

你能猜出打印答案时的CurrentThread.IsThreadPoolThread是什么吗?

似乎Task.Delay(..)正在执行此操作,因为如果我删除等待,则答案为False。但是,我似乎无法发现Delay实际上将东西放在文档中的线程池中。

这让我想到了更普遍的问题。任务中的内容实际上启动了Run(..)以外的线程池线程?

修改
new Task(...)

替换Ask()
    public static async void Ask()
    {
        int answer = await Answer();
        Console.WriteLine(answer + " " + Thread.CurrentThread.IsThreadPoolThread);
    }

产生相同的结果

1 个答案:

答案 0 :(得分:3)

正如我在async / await intro帖子中描述的那样,默认情况下await将捕获当前的“上下文”并使用它来执行延续(await之后的代码)。此“上下文”为SynchronizationContext.Current,除非它是null,在这种情况下为TaskScheduler.Current

我还在我的博客上描述了using async on Console apps。控制台应用不提供SynchronizationContext,因此“上下文”会回退到TaskScheduler.Current。由于当前正在执行的Task正在线程池上运行,TaskScheduler.CurrentTaskScheduler.Default相同,后者是线程池任务调度程序。

这就是您的代码在线程池线程上恢复的原因。这是正确的行为。