私はチャットクライアントを構築していますが、dispatcher
の使用方法について100%確信が持てません。だから質問は、私はそのような方法を持っているということです:
public void LostConnection()
{
myGUI.chatBox.AppendText("Lost connection to room: "+ myGUI.UsernameText.ToString() + "\r\n");
}
(myGUI.chatBox... )
内のステートメントをDispatcher.Invoke
で囲む必要がありますか?私は助けに感謝します。
アプリにはメインUIスレッドがあります(通常は_ManagedThreadId==1
_)。通常、チャットアプリでは、イベントは他のスレッド(専用のソケットリスンスレッドまたはリスニングコードのスレッドプールスレッド)で発生します。他のスレッドをプルするイベントからUIを更新する場合は、ディスパッチャーを使用する必要があります。ここで役立つテストは、コードがUIスレッド上にある場合はtrueを返し、他のスレッド上にある場合はfalseを返すDispatcher.CheckAccess()
メソッドです。典型的な呼び出しは次のようになります。
_using System.Windows.Threading; // For Dispatcher.
if (Application.Current.Dispatcher.CheckAccess()) {
network_links.Add(new NetworkLinkVM(link, start_node, end_node));
}
else {
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(()=>{
network_links.Add(new NetworkLinkVM(link, start_node, end_node));
}));
}
_
メインウィンドウにいる場合は、次を使用できます。
_Dispatcher.BeginInvoke(...
_
ビューモデルなどの別のコンテキストにいる場合は、次を使用します。
_Application.Current.Dispatcher.BeginInvoke(
_
Invoke vs BeginInvoke
UIスレッドがディスパッチコードを処理するまで現在のスレッドを待機させる場合はInvoke
を使用し、操作が完了するのを待たずに現在のスレッドを続行させる場合はBeginInvoke
を使用しますUIスレッド。
MessageBox、Dispatchers、Invoke/BeginInvoke:
_Dispatcher.Invoke
_は、MessageBoxが閉じられるまでスレッドをブロックします。
_Dispatcher.BeginInvoke
_は、UIスレッドがMessageBox呼び出しで却下されるまでブロックする間、スレッドコードの実行を継続できるようにします。
CurrentDispatcher vs Current.Dispatcher!
_Dispatcher.CurrentDispatcher
_に注意してください。これは、これがUIスレッドではなく現在のスレッドのDispatcherを返すことを理解しているためです。一般的に、UIスレッドのディスパッチャに興味があります-_Application.Current.Dispatcher
_は常にこれを返します。
付記:
ディスパッチャCheckAccessを頻繁にチェックする必要がある場合、便利なヘルパーメソッドは次のとおりです。
_public void DispatchIfNecessary(Action action) {
if (!Dispatcher.CheckAccess())
Dispatcher.Invoke(action);
else
action.Invoke();
}
_
次のように呼び出すことができます:
_DispatchIfNecessary(() => {
network_links.Add(new NetworkLinkVM(link, start_node, end_node));
});
_
このようなもの(私の頭の上の)は動作するはずです:
public void LostConnection()
{
myGUI.Invoke
((MethodInvoker)delegate
{
myGUI.chatBox.AppendText("Lost connection to room: "+ myGUI.UsernameText.ToString() + "\r\n");
});
}
_Application.Current.Dispatcher.BeginInvoke
_およびobject.Invoke()
メソッドに問題がありました。
これは私のために働いた:
_Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
{
// code...
}));
_