c#异步等待和线程池

本文关键字:线程 等待 异步 | 更新日期: 2023-09-27 18:15:11

我明白,当在UI线程上调用的方法上使用async和await时,UI线程可以被释放去做其他工作,同时等待一些IO完成。如果我在线程池线程调用的方法上使用async await,该线程池线程会发生什么当IO完成时?它被放回游泳池了吗?当IO完成时,哪个线程完成后一种情况下的方法?

c#异步等待和线程池

在这种情况下,在任何可用的线程池线程上执行延续。

理论上,由可等待对象来适当地调度延续,但一般来说,当异步方法传入延续时,可等待对象捕获当前的SynchronizationContext,并在可等待对象完成时使用该同步上下文来调度延续。(模块ConfigureAwait调用等)

在线程池的情况下,没有同步上下文,因此延续只是在任何线程池线程上调度。(在控制台应用程序的主线程中也是如此——或者基本上任何没有设置同步上下文的线程。)

如果我在线程池线程调用的方法上使用异步等待,当IO完成时该线程池线程会发生什么?它被放回游泳池了吗?

是,线程池的线程被返回到线程池。

当IO完成时,哪个线程完成后一种情况下的方法?

默认情况下,await将捕获当前的"上下文",并在await完成时使用它来恢复async方法。这个"上下文"是SynchronizationContext.Current,除非它是null,在这种情况下,"上下文"是TaskScheduler.Current

在UI的情况下,有一个UI SynchronizationContext导致async方法在UI线程上恢复执行。在线程池的情况下,SynchronizationContext.Currentnull, TaskScheduler.Current是线程池任务调度器。因此,async方法在线程池线程(任何任意线程,不一定是同一个线程)上被恢复。

如果你想了解更多关于这个行为的信息,我有一个async的介绍,你可能会发现有帮助。