【问题标题】:C++/CX: Using Dispatcher to access UI thread doesn't workC++/CX:使用 Dispatcher 访问 UI 线程不起作用
【发布时间】:2018-12-25 16:53:24
【问题描述】:

我正在开发 UWP 应用程序,需要在非 UI 代码中使用 TextBlock 类。尝试实例化 TextBlock 对象会产生“RPC_E_WRONG_THREAD(应用程序调用了为不同线程编组的接口)”异常。 根据我在 Internet 上收集的信息,我知道我应该在 UI 线程中执行我的代码。我使用了以下代码:

CoreDispatcher^ dispatcher = CoreWindow::GetForCurrentThread()->Dispatcher;

dispatcher->RunAsync(CoreDispatcherPriority::Normal, ref new DispatchedHandler
                                                            [/* captured variables */]() {
    TextBlock ^text_block = ref new TextBlock();
    /* other code */
});

问题是,在尝试 TextBlock 实例化的那一刻,我收到了同样的异常。我做错了什么?

UPD: 我刚刚意识到我正在做的项目是一个 DirectX UWP 应用程序。是不是不能直接访问UI线程?

【问题讨论】:

  • 您正在构建的 UWP 应用是否打开了多个窗口?你在哪里运行这段代码?
  • GetForCurrentThread() 不是你想要的。谷歌“uwp get dispatcher”,第一次点击就不错了。
  • @HansPassant 我没有找到任何其他与 C++ 相关的解决方案
  • @MartinZikmund 据我所知,它只打开了一个窗口。我在 Windows 10 模拟器上运行它。

标签: uwp c++-cx


【解决方案1】:

CoreWindow::GetForCurrentThread() 获取CoreWindow 仅在从具有关联窗口的 UI 线程调用时才有效。相反,当您在后台线程上时,您必须以不同的方式访问 UI 线程:

Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
        CoreDispatcherPriority::Normal,
        ref new Windows::UI::Core::DispatchedHandler([this]()
{
   TextBlock ^text_block = ref new TextBlock();
   /* other code */
}));

这会找到应用程序主视图的CoreWindow 并获取其调度程序。优点是这种方法不使用GetForCurrentThread,因此您甚至可以在后台线程中使用它。

当您打开应用的多个视图时,这会成为一个问题 - 然后每个视图都有自己的 UI 线程,因此您必须知道此操作正在修改哪个视图,以便您知道您使用哪个调度程序想用。在这种情况下,您可以使用CoreApplication::Views 集合来枚举和访问所有应用程序视图。

【讨论】:

  • 遗憾的是,在使用您的代码示例时,我仍然遇到同样的异常。
  • 你不是想从后台任务运行它吗?
  • 不,它与 main 函数发生在同一个进程中,只是在不同的线程中。
猜你喜欢
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 2015-03-06
  • 1970-01-01
  • 2012-07-06
  • 1970-01-01
  • 2013-06-19
  • 2021-04-16
相关资源
最近更新 更多