0

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

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

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

4

1 回答 1

2

您不需要 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方法,以在拥有各自的线程上引发PropertyChanged事件DependencyObject

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
}
于 2018-06-20T22:01:30.303 回答