4

ユーザーが離れるたびに「画面」の観察可能なコレクションを変更する次のコードがあります。

void OnUserLeft(int roomId, int userId, string username)
    {
        client.ClientDispatcher.Invoke(
            (Action<int>)((id) => 
            {
                Console.WriteLine("Hello before the storm!");
                var screensToCheck = client.Screens.Where(s => s.CpuId == id).ToList();
                screensToCheck.Each(s => client.Screens.Remove(s));
                Console.WriteLine("Hello there!");
            }), userId);
    }

これは、おそらくCollectionViewsに関連するスレッドの問題を乗り越えるために、クライアントのDispatcherへの呼び出しにラップされています。ただし、それでも次の例外が発生します。

このタイプのCollectionViewは、Dispatcherスレッドとは異なるスレッドからのSourceCollectionへの変更をサポートしていません。

上記のディスパッチャーは、次のようにWPFアプリケーションのMainViewModel(MVVMを使用しています)に設定されています。

public Dispatcher ClientDispatcher
{
    get { return Dispatcher.CurrentDispatcher; }
}
4

1 に答える 1

6

のドキュメントからCurrentDispatcher

現在実行中のスレッドのディスパッチャーを取得し、まだスレッドに関連付けられていない場合は新しいディスパッチャーを作成します。

CurrentDispatcher UIスレッドを使用していないときにアクセスしていて、操作を呼び出しているようです(つまり、使用しているスレッドにディスパッチャーがないため、呼び出しはまったく効果がありません。新しいスレッドがその場で作成され、呼び出しはそれに行きます)。

Dispatcher.CurrentDispatcherインスタンスを作成する時点での値を保存する必要がありClientます(UIスレッド内から作成していると仮定します)。次に例を示します。

class Client {
    Client() {
        this.OwningDispatcher = Dispatcher.CurrentDispatcher;
    }

    Dispatcher OwningDispatcher { get; private set; }
}

インスタンスがUIスレッドで作成されていない場合は、Clientインスタンスに正しい値を取得するための何らかの方法が必要ですDispatcher

于 2010-05-13T21:52:39.453 に答える