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

WinRT/C++ What is apartment_context actually?

我知道的是apartment_context用于捕获UIThread,return到UIThread在后台ThreadPool时[=17] =]

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

最后,与resume_foreground()CoreDispatcher::RunAsync()相比,使用apartment_context的优点和缺点是什么?

谢谢

一个winrt::apartment_context

captures the thread context within a coroutine so that it can be restored later. You instantiate a winrt::apartment_context value, and then later you co_await it.

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

实现包装了一个 IContextCallback interface captured from a call to CoGetObjectContext. Its ContextCallback 方法

enters the object context, executes the specified function, and returns.

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

相比之下,apartment_context 的界面没有暴露任何复杂性。它由一个默认构造函数和三个成员 await_ready()await_suspend()await_resume() 组成,这三个成员使其成为 coroutine awaiter4. Consequently, the only operations client code performs is to construct, and co_await it. Examples and explanations can be found at Programming with thread affinity in mind.

至于优点和缺点,归结为了解发生了什么。虽然 apartment_context 像宣传的那样工作,但请务必记住,它捕获 current 上下文。因此,协程是否按预期工作成为调用者的责任。如果(部分)协程需要在 UI 线程上执行,则使用 resume_foreground 更健壮,也更具可读性。这里唯一的缺点是您需要访问调度程序。

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


1 What is so special about the Application STA?

2 How do you get into a context via IContext­Callback::Context­allback?

3 Using contexts to return to a COM apartment later

4 C++ Coroutines: Understanding operator co_await