异步和等待线程问题

时间:2016-11-17 20:49:39

标签: c# async-await task-parallel-library

我编写了一个程序来检查我是否理解async-await概念。

       static void Main(string[] args)
    {
        Run2().Wait();
    }

    static async Task DoAsyncWork()
    {
        await Task.Delay(2000);
    }

    static async Task Run2()
    {
        var tid = Thread.CurrentThread.ManagedThreadId;
        await DoAsyncWork();
        Console.WriteLine(tid == Thread.CurrentThread.ManagedThreadId);
    }

我有点困惑,会打印什么?

我认为我们无法保证会打印什么

我的解释: 调用await DoAsyncWork时,控件返回Main。 在DoAsyncWork完成控制返回并在等待之后继续其余代码之后。 其余的代码可以运行,我们没有保证关于女巫线程运行此代码。

实际上: 我运行此代码很多时间并打印False

1 个答案:

答案 0 :(得分:4)

await将使用SynchronizationContext.Current来确定如何执行延续代码。如果当前同步上下文中有一个值,并且同步上下文的特定实现最终会运行在特定线程上发送给它的所有代码,那么您总是会在同一个线程中运行代码。 (winforms或WPF应用程序设置的同步上下文将执行此操作。)

如果没有同步上下文(代码中就是这种情况),将使用默认值,它使用线程池,因此最终可能会在任何线程上运行。还有可能存在同步上下文集,该同步上下文集不必运行在同一线程上发送给它的所有代码。 (ASP应用程序使用的同步上下文将执行此操作。)

由于在您的代码中没有同步上下文,因此将使用线程池,并且线程将永远不会相同。如果您创建了一个消息循环,其中有一个同步上下文向其发送消息(例如,在启动winforms或WPF应用程序时会发生)并从中调用Run2,则线程将可靠地匹配。