【发布时间】:2014-07-27 20:13:05
【问题描述】:
我了解,当在 UI 线程上调用的方法上使用 async 和 await 时,可以释放 UI 线程来执行其他工作,同时等待某些 IO 完成。 如果我在线程池线程调用的方法上使用异步等待该线程池线程会发生什么 而IO完成?是回到游泳池吗?当 IO 完成后,哪个线程完成后一种情况下的方法?
【问题讨论】:
标签: c# multithreading asynchronous
我了解,当在 UI 线程上调用的方法上使用 async 和 await 时,可以释放 UI 线程来执行其他工作,同时等待某些 IO 完成。 如果我在线程池线程调用的方法上使用异步等待该线程池线程会发生什么 而IO完成?是回到游泳池吗?当 IO 完成后,哪个线程完成后一种情况下的方法?
【问题讨论】:
标签: c# multithreading asynchronous
在这种情况下,继续在任何可用的线程池线程上执行。
理论上,由 awaitable 来适当地安排延续,但通常当 async 方法传入延续时,awaitable 会捕获当前的SynchronizationContext,并在 awaitable 完成时使用该同步上下文来安排延续。 (模块ConfigureAwait调用等)
在线程池的情况下,没有同步上下文,所以延续只是调度在任何线程池线程上。 (在控制台应用程序的主线程上也是如此 - 或者基本上是任何尚未设置同步上下文的线程。)
【讨论】:
如果我在线程池线程调用的方法上使用异步等待,当 IO 完成时该线程池线程会发生什么?是否返回池中?
是的,线程池线程返回线程池。
当 IO 完成后,哪个线程完成后一种情况下的方法?
默认情况下,await 将捕获当前的“上下文”,并在 await 完成时使用它来恢复 async 方法。这个“上下文”是SynchronizationContext.Current,除非它是null,在这种情况下,“上下文”是TaskScheduler.Current。
在 UI 案例中,有一个 UI SynchronizationContext 导致 async 方法在 UI 线程上恢复执行。在线程池的情况下,SynchronizationContext.Current 是null,TaskScheduler.Current 是线程池任务调度器。因此,async 方法在线程池线程(任意线程,不一定是同一个线程)上恢复。
如果您想了解有关此行为的更多信息,我有一个 async intro,您可能会觉得有帮助。
【讨论】: