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