0

ハードウェア デバイスから電圧と電流を読み取る非 GUI オブジェクトがあります。これらの値が変更されると、オブジェクトはこれらのプロパティを変更し、INotifyPropertyChanged イベントを発生させる必要があります。

構造体 winrt::resume_foreground がありますが、これを使用して正しいスレッドに切り替えることができますが、コンストラクターには GUI オブジェクトへの参照が必要です (サンプル コード内)。

使用する必要がある正しいディスパッチャ オブジェクトをキャプチャする最適な方法は何ですか?

4

1 に答える 1

2

特定のスレッドに切り替えるのに GUI は必要ありません。代わりに、エントリ時に呼び出しコンテキストをキャプチャし、いつでもそれに切り替えることができます。これについては、スレッド アフィニティを念頭に置いたプログラミングで、コード例とともに説明されています。

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メソッドを呼び出して、それぞれを所有するスレッドでPropertyChangedDependencyObjectイベントを発生させることができます。

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 に答える