Почему `agile_ref` не работает с некоторыми объектами, такими как` CoreWindow`? - PullRequest
0 голосов
/ 02 июня 2018

C ++ / WinRT 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);
}

Run() вызывается в потоке пользовательского интерфейса, а затем пытаетсясоздайте гибкую ссылку, а затем используйте ее для вызова CoreWindow из пула потоков.Однако это не работает с "The application called an interface that was marshaled for a different thread." Так как agile_ref использует RoGetAgileReference внутренне для маршалинга объекта, и вызовы для создания ссылки, а затем демаршалирования ее обоих успешны, мне кажется, что CoreWindow просто отказывается бытьвообще маршалировал.

Если, конечно, это не работает как задумано, и вызов RoGetAgileReference молча не в состоянии маршалировать CoreWindow.

Так что вызывает вызов SetPointerCapture ксбой, даже с agile_ref?

1 Ответ

0 голосов
/ 09 июня 2018

Ошибка вводит в заблуждение.Большинство классов Windows.UI на самом деле гибкие.Проблема заключается в том, что они выполняют явную проверку потока, чтобы убедиться, что вы действительно вызываете их из соответствующего потока пользовательского интерфейса.Вот почему agile_ref не поможет.Решение состоит в том, чтобы использовать Dispatcher, который направляет вас в нужную цепочку.Затем вы можете просто вызвать методы непосредственно для объекта.

...