我正在使用WRL将常规C ++应用程序移植到C ++中。我有一个现有的线程池,有些我需要从其中一个线程更新UI。
直接触摸UI对象会产生预期的RPC_E_WRONG_THREAD,所以我需要以某种方式在正确的线程中执行。在MSDN中查看我发现Metro调度程序(CoreDispatcher)有一个RunAsync方法。
Larry Osterman在这里回答了如何使用它的问题: Run code on UI thread in WinRT
但不清楚的是,我是否可以从非winrt线程中做到这一点,即来自未调用RoInitialize的线程。
我想更准确一点,我担心调度员可能属于STA,我需要以某种方式封送接口,以便从我的其他线程调用是安全的。
请注意,msdn示例后我的应用程序的main()函数调用RoInitialize(RO_INIT_MULTITHREADED)。
答案 0 :(得分:1)
你应该可以从非UI线程调用CoreDispatcher :: RunAsync。但有一些警告: 1)你需要在地铁风格的应用程序(这应该不用说)。原因是应用程序对象创建了一个在应用程序生命周期中存在的MTA。 COM的这个漂亮功能称为隐式MTA - 如果MTA存在于您的进程中,则任何线程都被认为是该MTA的一部分,即使它们没有调用CoInitialize。
这意味着当您访问CoreDispatcher :: RunAsync时,即使您需要代理对象,MTA也处于活动状态,因此编组应该会成功。
请注意,应用启动期间有一段时间可能尚未创建应用程序对象 - 在应用程序代码执行之前,您应该避免执行任何操作。
2)您需要捕获要使用的UI线程上的CoreDispatcher对象。 Xaml基础架构已经在DependencyObject中捕获了调度程序,这使事情变得更加容易。因此,如果您已经拥有Xaml UI元素,则可以调用.Dispatcher.RunAsync()。
PS:UI线程在ASTA上(应用程序STA,Win8中添加的一种新型公寓),但调度程序是线程敏捷的。请注意,虽然调度程序是敏捷的,但不应将CoreWindow视为敏捷。