我有一个从硬件设备读取电压和电流的非 gui 对象。当这些值更改时,对象需要更改这些属性并引发 INotifyPropertyChanged 事件。
有一个 struct winrt::resume_foreground,但是可以用来切换到正确的线程,但是构造函数需要一个 GUI 对象的引用(在示例代码中)。
捕获应该使用的正确调度程序对象的最佳方法是什么?
我有一个从硬件设备读取电压和电流的非 gui 对象。当这些值更改时,对象需要更改这些属性并引发 INotifyPropertyChanged 事件。
有一个 struct winrt::resume_foreground,但是可以用来切换到正确的线程,但是构造函数需要一个 GUI 对象的引用(在示例代码中)。
捕获应该使用的正确调度程序对象的最佳方法是什么?
您不需要 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
}