1

私は signalR を使用してメッセージをサーバーにプッシュし、特定のクライアントにプッシュしています。

メッセージを送信すると、受信側のクライアントに signalR サーバーから ReceiveMessage 関数呼び出しが送信され、アプリの静的クラス関数にマップされます。次に、静的クラスはnew Chat()(私のメッセージング ウィンドウ クラス) を実行して、受信側でメッセージ ウィンドウを開こうとします。

これはスローしますcalling thread must be STA, because many UI components require this.

以前に単純なフォーム要素 (テキスト ボックスの変更など) でデリゲートを使用したことがありますが、この状況でそれを適用する方法がわかりません。について読んだときInvoke、私の状況には存在しないある種のフォームオブジェクトで呼び出されましたか?

TLDR; 静的クラス関数呼び出しからフォームの新しいインスタンスを作成して表示する方法

4

3 に答える 3

5

現在の GUI のスレッド ディスパッチャを使用します。次に、invoke を呼び出します。例:

Application.Current.Dispatcher.Invoke(() => { 
      var win = new Window();
      win.show(); 
});
于 2012-07-30T14:44:39.947 に答える
2

最も簡単: を使用App.MainWindow.Dispatcherして、GUI スレッドで作成を実行します。

App.MainWindow.Dispatcher.BeginInvoke((Action)(() => { new Chat(); }));

難しい: 新しい STA スレッドを作成し、その上に新しいウィンドウを作成します。

後者のオプションは、複数の GUI スレッドがあり、それぞれの場合に適切なスレッドが使用されるように操作を追跡する必要があるため、より困難です。複数の GUI スレッドを簡単なオプションに固定する特定の理由がない限り。

于 2012-07-30T14:41:43.193 に答える
0

UI スレッドでコードを呼び出す必要があります。これを行うには、同期コンテキストへの参照が必要です。UI スレッドから次のコードを呼び出したとします。

SynchronizationContext syncContext = SynchronizationContext.Current;

これにより、コンテキストへの参照が得られました。

次に、コールバック メソッド (バックグラウンド スレッド (UI ではない) でメッセージを受信した後) で、次の操作を実行できます。

syncContext.Post((state) =>
                {
                    Window w = new Window(); 

                }, ...);

ラムダ式のコードは、UI スレッドに代わって実行されます。私の知る限り、これは「Control.Invoke」と「Dispatcher.Invoked」の両方のアプローチで実際に舞台裏で起こっていることです。

于 2012-07-30T14:49:03.517 に答える