为什么`agile_ref`会因某些对象而失败,例如`CoreWindow`?

时间:2018-06-02 05:11:24

标签: windows uwp c++-winrt

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

1 个答案:

答案 0 :(得分:1)

该错误具有误导性。大多数Windows.UI类实际上都是敏捷的。挑战在于它们执行显式线程检查以确保您实际从相应的UI线程调用它们。这就是agile_ref无法帮助的原因。解决方案是使用Dispatcher,它可以让您使用正确的线程。然后,您可以直接在对象上调用方法。