uwp - C++/CX:使用 Dispatcher 访问 UI 线程不起作用
问题描述
我正在开发 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线程?
解决方案
Get CoreWindow
fromCoreWindow::GetForCurrentThread()
仅在从具有关联窗口的 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
集合来枚举和访问所有应用程序视图。
推荐阅读
- forms - Phoenix 框架模板中的自定义选择
- python - 通过 * 或 ** 将参数传递给函数
- prometheus - 使用 Prometheus 监控 OOM
- playframework - Play Framework:如何处理内存密集型动作?
- google-apps-script - 如何使用 Google App Script 在 google 电子表格上获取毫秒详细信息
- python - 如何仅使用python的请求模块登录oddsportal.com?
- mysql - Django 请求的会话在请求完成之前被删除。用户可能已经在并发请求中注销,例如
- powerbi - 向现有列添加条件
- r - 即使没有要绘制的点,也显示完整的分类 x 轴
- python - Python 错误“ModuleNotFoundError: No module named 'requests'”