我以为还在等待与调用者相同的线程,但似乎没有
我认为关于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.Current
与TaskScheduler.Default
(线程池任务调度程序)相同)。
值得注意的是, SynchronizationContext
或TaskScheduler
并不一定意味着特定的线程 。 UI SynchronizationContext
将为UI线程安排工作; 但ASP.NET SynchronizationContext
不会为特定线程安排工作。
我怀疑你的问题的原因是你过早地调用async
代码。 当应用程序启动时,它只有一个普通的常规线程。 当该线程执行类似Application.Run
时,该线程仅成为UI线程。
await
表达式将使用SynchronizationContext.Current
的值将控制流返回到发生它的线程。 如果为null
,则默认为TaskScheduler.Current
。 当Task
值完成时,实现仅依赖于此值来更改线程上下文。 听起来在这种情况下, await
正在捕获未绑定到UI线程的上下文