C ++ / WinRT' s agile_ref
据称允许以敏捷方式使用非敏捷对象。
但是,我发现至少CoreWindow
个实例失败了。
作为一个简短的例子:
void Run()
{
auto window{ CoreWindow::GetForCurrentThread() };
window.Activate();
auto agile_wnd{ make_agile(window) };
ThreadPool::RunAsync([=](const auto&) {
auto other_wnd{ agile_wnd.get() };
other_wnd.SetPointerCapture();
});
auto dispatcher{ window.Dispatcher() };
dispatcher.ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit);
}
在UI线程上调用 Run()
,然后尝试创建敏捷引用,然后使用它从线程池调用CoreWindow
。但是,"The application called an interface that was marshaled for a different thread."
由于agile_ref
在内部使用RoGetAgileReference
来封送对象,并且创建引用然后解组它的调用都在成功,这在我看来是{ {1}}根本就拒绝被封锁。
当然,除非这是按预期工作的,CoreWindow
调用无声地无法整理RoGetAgileReference
。
那么导致CoreWindow
调用失败的原因是什么,即使使用SetPointerCapture
?
答案 0 :(得分:1)
该错误具有误导性。大多数Windows.UI类实际上都是敏捷的。挑战在于它们执行显式线程检查以确保您实际从相应的UI线程调用它们。这就是agile_ref无法帮助的原因。解决方案是使用Dispatcher,它可以让您使用正确的线程。然后,您可以直接在对象上调用方法。