2

WRLを使用して、通常のC++アプリをC++のメトロに移植しています。既存のスレッドプールがあり、その時点で、これらのスレッドの1つからUIを更新する必要があります。

UIオブジェクトに直接触れると、期待されるRPC_E_WRONG_THREADが得られるため、適切なスレッドで実行する必要があります。MSDNを見ると、メトロディスパッチャー(CoreDispatcher)にRunAsyncメソッドがあることがわかりました。

Larry Ostermanは、ここでそれをどのように使用するかという質問に答えます 。WinRTのUIスレッドでコードを実行します。

しかし、明確ではないのは、Winrt以外のスレッド、つまりRoInitializeを呼び出していないスレッドからそれを実行できるかどうかです。

もっと正確に言うと、ディスパッチャがSTAに属している可能性があり、他のスレッドから安全に呼び出すことができるように、何らかの方法でインターフェイスをマーシャリングする必要があるのではないかと思います。

msdnサンプルに続く私のアプリのmain()関数は、RoInitialize(RO_INIT_MULTITHREADED)を呼び出すことに注意してください。

4

1 に答える 1

1

UI以外のスレッドからCoreDispatcher::RunAsyncを呼び出しても問題ありません。ただし、いくつかの注意点があります。1)メトロスタイルアプリを使用する必要があります(これは言うまでもありません)。その理由は、アプリケーションオブジェクトが、アプリケーションの存続期間中存続するMTAを作成するためです。暗黙的なMTAと呼ばれるCOMのこの気の利いた機能があります-MTAがプロセスに存在する場合、CoInitializeを呼び出さなくても、スレッドはそのMTAの一部であると見なされます。

つまり、CoreDispatcher :: RunAsyncにアクセスすると、オブジェクトをプロキシする必要がある場合でも、MTAがアクティブになるため、マーシャリングは成功するはずです。

アプリの起動中に、アプリケーションオブジェクトがまだ作成されていない可能性がある期間があることに注意してください。アプリケーションのコードが実行されるまで、何もしないでください。

2)使用するUIスレッドでCoreDispatcherオブジェクトをキャプチャする必要があります。これは、XamlインフラストラクチャがすでにDependencyObjectのディスパッチャーをキャプチャしているという事実によって簡単になります。したがって、すでにXaml UI要素がある場合は、.Dispatcher.RunAsync()を呼び出すだけです。

PS:UIスレッドはASTA(アプリケーションSTA、Win8で追加された新しい種類のアパートメント)上にありますが、ディスパッチャーはスレッドアジャイルです。ディスパッチャはアジャイルですが、CoreWindowはアジャイルと見なされるべきではないことに注意してください。

于 2012-05-22T05:08:54.647 に答える