我以为还在等待与调用者相同的线程,但似乎没有

我认为关于async / await的一点是,当任务完成时,继续在调用await时在相同的上下文上运行,在我的情况下,这将是UI线程。

例如:

Debug.WriteLine("2: Thread ID: " + Thread.CurrentThread.ManagedThreadId); await fs.ReadAsync(data, 0, (int)fs.Length); Debug.WriteLine("3: Thread ID: " + Thread.CurrentThread.ManagedThreadId); 

我不指望这个:

 2: Thread ID: 10 3: Thread ID: 11 

是什么赋予了? 为什么延续的线程ID与UI线程不同?

根据这篇文章 [^]我需要显式调用ConfigureAwait来改变连续上下文的行为!

当您await ,默认情况下, await运算符将捕获当前的“上下文”并使用它来恢复async方法。

这个“上下文”是SynchronizationContext.Current除非它是null ,在这种情况下它是TaskScheduler.Current 。 (如果当前没有正在运行的任务,则TaskScheduler.CurrentTaskScheduler.Default (线程池任务调度程序)相同)。

值得注意的是, SynchronizationContextTaskScheduler并不一定意味着特定的线程 。 UI SynchronizationContext将为UI线程安排工作; 但ASP.NET SynchronizationContext不会为特定线程安排工作。

我怀疑你的问题的原因是你过早地调用async代码。 当应用程序启动时,它只有一个普通的常规线程。 当该线程执行类似Application.Run时,该线程仅成为UI线程。

await表达式将使用SynchronizationContext.Current的值将控制流返回到发生它的线程。 如果为null ,则默认为TaskScheduler.Current 。 当Task值完成时,实现仅依赖于此值来更改线程上下文。 听起来在这种情况下, await正在捕获未绑定到UI线程的上下文