私のWPFアプリケーションでは、サーバーと非同期で通信します。したがって、コールバックはUIスレッドで実行されません。そこで、いくつかのWPF処理(InkPresenterオブジェクトの作成)を行う必要があるため、UIスレッドで実行する必要があります。実際の要件は、STAアパートメントモードのスレッドで実行することです。STAモードで新しいスレッドを作成しようとしましたが、「別のスレッドが所有している」ため、UIスレッドがInkPresenterにアクセスできませんでした。
コールバックで実行したいのは、ディスパッチャーを使用して、STAを必要とする関数を呼び出すことです。これは正しいアプローチのように聞こえますか?私は今これをします、しかしそれはまだ失敗します。コールバック関数で次の関数をトリガーします。これにより、アドレス指定された関数がUIスレッドで実行されるようになります。
private void UpdateAnnotationsForCurrentFrameCollection()
{
if (Dispatcher.CurrentDispatcher.CheckAccess())
{
DoSomethingIncludingInkPresenter();
}
else
{
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Normal,
new Action(DoSomethingIncludingInkPresenter));
}
}
private void DoSomethingIncludingInkPresenter()
{
var inkPresenter = XamlReader.Parse(_someXamlString) as InkPresenter;
// Do something with the inkPresenter..
}
サンプルからわかるように、CheckAccess()を使用して、UIスレッドでまだ実行されていない場合にのみ関数を呼び出すようにします。私のコールバックがこの関数を呼び出すとき、CheckAccess()は常にtrueですが、Dispatcher.CurrentDispatcher.Thread.ApartmentState
MTAです。なんで?CheckAccess()を削除して常にInvokeを実行しようとしましたが、ApartmentStateはMTAのままであり、InkPresenterの作成は失敗します。
ここで私が間違っていることを誰かに説明してもらえますか?間違ったディスパッチャーか何かを持っていますか?これは、UIスレッドで何かが実行されるようにするための正しいアプローチですか?