如何在C ++ / winrt中的正确线程上从视图模型对象引发INotifyPropertyChanged

时间:2018-06-20 21:36:43

标签: c++-winrt

我有一个非GUI对象,可以从硬件设备读取电压和电流。当这些值更改时,对象需要更改这些属性并引发INotifyPropertyChanged事件。

有一个结构winrt :: resume_foreground,但是可以用来切换到正确的线程,但是构造函数需要引用GUI对象(在示例代码中)。

捕获应该使用的正确调度程序对象的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

您不需要GUI即可切换到特定线程。相反,您可以在进入时捕获调用上下文,然后随时切换到该上下文。在Programming with thread affinity in mind下以及代码示例中对此进行了解释:

IAsyncAction DoWorkAsync(TextBlock textblock)
{
    winrt::apartment_context ui_thread; // Capture calling context.

    co_await winrt::resume_background();
    // Do compute-bound work here.

    co_await ui_thread; // Switch back to calling context.

    textblock.Text(L"Done!"); // Ok if we really were called from the UI thread.
}

或者,如果您有权访问DependencyObject,则可以将其Dispatcher属性用于winrt::resume_foreground类:

IAsyncAction DoWorkAsync(DependencyObject targetObject)
{
    co_await winrt::resume_background();
    // Do compute-bound work here.

    co_await winrt::resume_foreground(targetObject.Dispatcher());

    // Raise INotifyPropertyChanged event.
}

同样,您可以从协程调用CoreDispatcher.RunAsync方法,以在拥有相应DependencyObject的线程上引发PropertyChanged事件:

IAsyncAction DoWorkAsync(DependencyObject targetObject)
{
    co_await winrt::resume_background();
    // Do compute-bound work here.

    co_await targetObject.Dispatcher().RunAsync(CoreDispatcherPriority::Normal,
                                                [=]()
    {
        // Raise event
    });

    // Continue work
}