Windows 8 从遗留后台线程使用CoreDispatcher::RunAsync 我用WRL移植C++中的C++应用程序到Metro中。我有一个现有的线程池,我需要从其中一个线程更新UI

Windows 8 从遗留后台线程使用CoreDispatcher::RunAsync 我用WRL移植C++中的C++应用程序到Metro中。我有一个现有的线程池,我需要从其中一个线程更新UI,windows-8,windows-runtime,Windows 8,Windows Runtime,直接触摸UI对象会产生预期的RPC_E_错误的_线程,因此我需要以某种方式在正确的线程中执行。查看MSDN,我发现metro dispatcher(CoreDispatcher)有一个RunAsync方法 Larry Osterman在这里回答了如何使用它的问题: 但不清楚的是,我是否可以从一个非winrt线程,也就是从一个没有调用RoInitialize的线程来实现这一点 我想更确切地说,我担心调度器可能属于STA,我需要以某种方式封送接口,以便从我的另一个线程安全地调用 请注意,在msdn

直接触摸UI对象会产生预期的RPC_E_错误的_线程,因此我需要以某种方式在正确的线程中执行。查看MSDN,我发现metro dispatcher(CoreDispatcher)有一个RunAsync方法

Larry Osterman在这里回答了如何使用它的问题:

但不清楚的是,我是否可以从一个非winrt线程,也就是从一个没有调用RoInitialize的线程来实现这一点

我想更确切地说,我担心调度器可能属于STA,我需要以某种方式封送接口,以便从我的另一个线程安全地调用


请注意,在msdn示例之后,my app的main()函数调用RoInitialize(RO_INIT_MULTITHREADED)。

您应该可以从非UI线程调用CoreDispatcher::RunAsync。但有几个警告: 1) 你需要使用metro风格的应用程序(不用说)。原因是application对象创建的MTA在应用程序的生命周期内有效。COM有一个漂亮的特性,称为隐式MTA——如果进程中存在MTA,则任何线程都会被视为该MTA的一部分,即使它们没有调用CoInitialize

这意味着,当您访问CoreDispatcher::RunAsync时,即使您需要代理对象,MTA也会处于活动状态,因此封送应该会成功

请注意,在应用程序启动期间,有一段时间可能尚未创建应用程序对象-在执行应用程序代码之前,应避免执行任何操作

2) 您需要在要使用的UI线程上捕获CoreDispatcher对象。由于Xaml基础设施已经在中捕获了调度器,因此这变得更加容易。因此,如果您已经有一个Xaml UI元素,那么只需调用.Dispatcher.RunAsync()


PS:UI线程位于ASTA(应用程序STA,Win8中添加的一种新单元)上,但调度程序是线程敏捷的。请注意,虽然dispatcher是敏捷的,但CoreWindow不应被视为敏捷的。

dispatcher将使委托目标在另一个线程上执行,这就是使用它的要点。因此,如果该代码使用您的数据,那么就由您来确保线程安全。您可以在调用之前简单地准备数据,这样就不成问题了。Hans,问题不在于我的数据/对象的线程安全性,而在于在COM中,您必须知道每个对象所在的单元。所以,一般来说,如果我为IAgileObject查询接口并成功,那么我可以假设我不需要封送COM样式吗?你说的“我可以假设我不需要封送COM样式吗”-你从来没有“封送COM样式”,你调用方法,然后在幕后封送发生。你什么都不用做。IAgileObject可以让您确定地知道不必将对象放入GIT中。