【问题标题】:In what thread is executed the check for whether an awaitable has completed?在哪个线程中执行检查是否已完成等待?
【发布时间】:2017-05-20 20:56:46
【问题描述】:

假设我有一个方法

async Task<int> GetStackOverflowAsync()
{
    Task<int> longRunningCpuBoundTask = Task<int>.Run(() => 
       {
            // some long-running CPU-bound task that returns an int
       })
       .ConfigureAwait(continueOnCapturedContext: true);
    return await longRunningCpuBoundTask;
}

假设捕获的上下文是一个需要int 的 UI 线程。所以我知道Task.Run 将长时间运行的 CPU 绑定任务卸载到另一个线程,但我想知道哪个线程检查该任务的完成情况。

我想象会发生什么

UI 线程 |- 做 UI 的东西 -||- 检查 longRunningCpuBoundTask -||- 做更多的 UI 的东西 -||- 检查 longRunningCpuBoundTask |- 从我们在等待处离开的开始 -| longRunningCpuBoundTask 线程 |------------------------------------------------------------ - - - - - - - 完毕! ---------------------------------------|

有人可以纠正我的理解吗?

【问题讨论】:

  • 系统中没有部分轮询任务以查看它是否已完成。相反,一旦任务完成,编译器生成的代码会调用捕获的 SynchronizationContext 来安排更多工作。

标签: c# .net multithreading asynchronous async-await


【解决方案1】:

任务完成没有轮询。当任务完成时,基础结构代码调用SynchronizationContext.Post 以在 SynchronizationContext 认为必要的任何线程/其他上下文上完成操作。由 SynchronizationContext 决定如何调度线程上的操作。

在 WinForms(UI 上下文)的情况下,它最终会将常规 Windows 消息发布到控件,并且当消息被处理时(类似于任何其他消息,如“鼠标单击”),将执行 await 后的代码。

所以流程大致如下。

  UI thread                     |  Other thread    
  start click event
    start new task (if await'ed |
     save rest of the method    |
     as continuation delegate)  |
  return from click event       |    - thread created or obtained from pool
  handle mouse event            |    do work
  handle key event              |    do work
  handle mouse event            |    done - call Post on context
  ...                           |    post "special" message to event loop for the app
  handle mouse event            |    - thread closed or returned to pool
  handle "special" event - run  |    -
  continuation delegate)        |

请注意,没有检查线程的状态。您还可以看到 wait causes deadlock 如果在“处理特殊事件”之前的事件处理程序将如何由于 Thread.Sleep 或任何其他忙等待而停止处理其他 Windows 事件。

您可以通读WindowsFormsSynchronizationContext.Post 的代码以确切了解正在发生的事情(BeginInvoke 反过来会导致消息发布到常规事件循环)。还有很多关于这个话题的问题,比如What does SynchronizationContext do?

【讨论】:

    猜你喜欢
    • 2014-03-18
    • 1970-01-01
    • 2021-11-15
    • 2011-02-15
    • 1970-01-01
    • 2021-06-21
    • 2014-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多