3

请考虑以下代码

    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(..)正在这样做,因为如果我删除 await,那么答案是False. 但是,我似乎找不到Delay实际上将东西放在文档中的线程池中。

这让我想到了一个更普遍的问题。Task 中的什么实际上启动了一个线程池线程Run(..)

编辑:
替换new Task(...)Ask()

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

产生相同的结果

4

1 回答 1

3

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

我还在我的博客上描述了在控制台应用程序上的使用。async控制台应用程序不提供SynchronizationContext,因此“上下文”回退到TaskScheduler.Current. 由于当前执行Task的是在线程池上运行,TaskScheduler.Current所以和 一样TaskScheduler.Default,都是线程池任务调度器。

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

于 2012-11-01T20:23:58.880 回答