6

ジオスペースマップが埋め込まれたプログラムがあります。マップのイベント処理は、マップの応答性を維持するために別のスレッドで処理されます(たとえば、マップがクリックされたときに発生するイベント)。

私が抱えている問題は、マップがイベントを発生させたときに、プログラムがGUI内のいくつかのものを更新し、マップに写真を配置するためにマップにコールバックする必要があることです。

イベントハンドラーメソッド全体をthis.Dispatcher.Invokeでラップしてみました。これにより、メインUIスレッドに戻ります。これはGUIの更新には最適ですが、マップにコールバックしても、まだUIスレッドを使用しているため、マップに問題が発生する可能性があります。

基本的に、これを機能させるには、GUIのコントロールを変更するたびにdispatcher.invokeを実行する必要があります。各呼び出しをdispatcher.invokeでラップせずに、これを自動的に実行できる方法はありますか?これがすべて理にかなっていることを願っています。

これが私が話しているイベントのサンプルコードです。

    private void Map_OnMapClicked(object sender, MapClickedEventArgs e)
    {
        this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
        {
            // Do something to update my gui
        }));

        Map.DoSomethingInTheMap();

        this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
        {
            // Do something to update my gui
        }));


        //etc etc etc
    }
4

2 に答える 2

6

それぞれの操作を独自の同期コンテキストで維持する必要がある場合は、残念ながらこれが最善のアプローチです。GUIを更新するたびに、ディスパッチャを使用して呼び出す必要があります。

これを簡単にするためのいくつかの提案を次に示します。

  1. GUI操作をバッチ処理してみてください。必要なコードが少なくなる(呼び出し呼び出しが少なくなる)ことに加えて、パフォーマンスが向上します。各Dispatcher.Invoke呼び出しは、処理する必要のあるDispatcherのメッセージキューにメッセージを投稿するため、かなりのオーバーヘッドが発生します。

  2. 本当に待つ必要がない限り、ブロックを回避するためにDispatcher.BeginInvokeの使用を検討してください。

  3. .NET 4からタスク並列ライブラリ(またはRxフレームワークでは3.5sp1へのバックポート)を使用できる場合は、GUIスレッドに同期されたタスクインスタンスを使用するようにこれを作り直すことを検討してください。FromCurrentSynchronizationContextを使用してTaskSchedulerを作成することにより、DispatcherInvoke呼び出しよりも簡単にGUIで実行するようにタスクをスケジュールできます。これにより、バッチをスケジュールし、必要に応じて非常に簡単にブロック/待機できるため、バッチをある程度制御することもできます。

于 2010-02-05T23:02:52.560 に答える
2

PostSharpのようなものを使用するか、UIの更新を1回呼び出して多くのことを行う単一のメソッド呼び出しに凝縮してみることができます。または、このようなパターン(Winformsですが、考え方は同じです):

private void UpdateToolStripItemText(ToolStripItem toolStripItem, string text)
{
    if (InvokeRequired)
    {
        Invoke(new UpdateToolStripItemTextDelegate(UpdateToolStripItemText), new object[] { toolStripItem, text });
    }
    else
    {
        if (text != null)
        {
            toolStripItem.Text = text;
        }
    }
}
于 2010-02-05T23:05:25.720 に答える