WinRT/C++实际上什么是apartment_context



我所知道的是,apartment_context用于捕获UI线程,并在后台ThreadPool中返回到UI线程。

那么,apartment_context在WinRT/C++中究竟是什么呢?如何正确使用它?那么,这个对象只能捕获UI线程吗?

最后,与resume_foreground()CoreDispatcher::RunAsync()相比,使用apartment_context有哪些优点和缺点?

感谢

winrt::apartment_context

捕获协程中的线程上下文,以便稍后恢复。您实例化winrt::apartment_context值,然后稍后co_await它。

换句话说,它允许客户端代码存储关于当前线程的单元的信息,切换到另一个单元,然后返回到它。它可以在任何线程上构建,而不仅仅是UI线程。然而,由于UI线程位于特殊的1ASTA(应用程序单线程单元(中,并且这些线程所拥有的对象通常具有线程亲和性,因此apartment_context主要用于UI线程。

该实现封装了从对CoGetObjectContext的调用中捕获的IContextCallback接口。其ContextCallback方法

进入对象上下文,执行指定的函数,然后返回。

这是相当先进的,几乎没有官方文档可用。幸运的是,Raymond Chen已经发表了两篇博客文章2,3,详细介绍了这一领域。

相比之下,apartment_context的接口并没有暴露出任何这种复杂性。它由一个默认构造函数和三个成员await_ready()await_suspend()await_resume()组成,这三个成员使它成为协程awaiter4。因此,客户端代码执行的唯一操作就是构造和co_await。可以在Programming中找到考虑到线程亲和性的示例和解释。

至于优点和缺点,归根结底是了解发生了什么。虽然apartment_context如广告所示工作,但重要的是要记住,它捕捉到了当前的上下文。因此,协同程序是否按预期工作成为调用者的责任。如果协同程序(的一部分(需要在UI线程上执行,那么使用resume_foreground更健壮,可读性也更高。这里唯一的缺点是您需要访问调度器。

最后,CoreDispatcher::RunAsync最终也做了同样的事情。除了,它是Windows运行时的一部分,而resume_foreground()是C++/WinRT库的一部分。我没有意识到任何功能上的差异。


1 应用程序STA有什么特别之处

2 如何通过IContext­Callback::Context­allback进入上下文

3 使用上下文稍后返回COM单元

4 C++推论:理解算子co-await

最新更新