嵌套async-await下CPU密集型任务是否在线程池线程执行?线程是否一致?
C#异步线程执行疑问解答
以下代码中OnButtonClick由UI线程触发:
async void OnButtonClick() { await Task.Run(DoWork); } static async Task DoWork() { // Do Something // Do something else await DoSubWork(); // Do yet another thing } static async Task DoSubWork() { DoCpuBoundWorkOne(); await DoIOBoundWork(); DoCpuBoundWorkTwo(); } static void DoCpuBoundWorkOne() { // Do something } static async Task DoIOBoundWork() { // Do something } static void DoCpuBoundWorkTwo() { // Do something }
问题1:DoCpuBoundWorkTwo是否仍在线程池线程上执行?
是的,DoCpuBoundWorkTwo会在线程池线程上执行。
Task.Run会将DoWork的执行调度到线程池线程,而DoSubWork中的await DoIOBoundWork()运行在无UI同步上下文的线程池环境中,await完成后会回到线程池的某个可用线程(不一定是之前的线程,但肯定属于线程池),因此后续的DoCpuBoundWorkTwo会在线程池线程上运行。
问题2:若中间未显式调用ConfigureAwait(false),该任务是否始终在OnButtonClick中Task.Run启动的同一个线程上执行?
不会始终在同一个线程上执行。
线程池的核心逻辑是复用空闲线程,即使没有调用ConfigureAwait(false),当await完成后,线程池会分配一个可用线程来继续执行后续代码,而非强制复用之前的线程。只有当代码捕获了特定同步上下文(比如UI上下文)时,才会回到对应上下文的线程,但此处Task.Run启动的任务运行在无特定同步上下文的线程池环境中,所以后续执行的线程可能会发生变化。
内容的提问来源于stack exchange,提问作者Joerg
相关产品推荐
相关产品推荐

