C# 异步和等待线程问题

C# 异步和等待线程问题,c#,async-await,task-parallel-library,C#,Async Await,Task Parallel Library,我写了一个程序来检查我是否理解异步等待的概念 static void Main(string[] args) { Run2().Wait(); } static async Task DoAsyncWork() { await Task.Delay(2000); } static async Task Run2() { var tid = Thread.CurrentThre

我写了一个程序来检查我是否理解异步等待的概念

       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);
    }
我有点困惑,会打印什么

我想我们无法保证将打印什么

我的解释是: 当调用
wait DoAsyncWork
时,控件返回Main。 在
DoAsyncWork
之后,完成控制返回,并在等待后继续执行其余代码。 剩下的代码可以运行,我们不能保证witch线程可以运行这段代码

实际上:
我多次运行此代码并得到
False
打印。

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

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


因为在您的代码中没有同步上下文,所以将使用线程池,并且线程永远不会相同。如果您创建了一个消息循环,其中包含一个将消息定向到它的同步上下文(比如,启动winforms或WPF应用程序时会发生),并由此调用
Run2
,那么线程将可靠地匹配。

您将问多少次相同的问题?我们没有关于运行此代码的保证。如果
await
将安排继续而不是仅仅继续(如果看到已完成的任务,它将这样做),那么我们可以保证继续将在
线程池
线程之一上运行。和以前一样,wait使用not
ThreadPool
thread,那么它保证线程会不同。你真的应该停止一次又一次地问同样的问题。最好阅读本文:因此,如果wait关键字前后的上下文相同,那么线程将相同?@maz如果在
wait
之前没有默认上下文,那么将由调用线程和上下文继续的上下文决定,假设
await
有东西要等待,但任务尚未完成,在这种情况下,将在当前线程中继续执行。@PetSerAl您能举个例子吗,假设上下文是asp上下文吗?@maz具体是什么例子?我对ASP上下文实现的细节不是特别熟悉。