使用C#Dispatcher

我正在建立一个聊天客户端,并不是100%确定如何使用dispatcher 。 所以问题是我有一个方法:

 public void LostConnection() { myGUI.chatBox.AppendText("Lost connection to room: "+ myGUI.UsernameText.ToString() + "\r\n"); } 

我是否需要使用Dispatcher.Invoke来表达(myGUI.chatBox... )的语句? 我感谢任何帮助。

您的应用有一个主UI线程(通常是ManagedThreadId==1 )。 通常在聊天应用程序中,您的事件将进入其他线程(专用套接字侦听线程或来自侦听代码的线程池线程)。 如果要从某个其他线程获取的事件更新UI,则必须使用调度程序。 这里有用的测试是Dispatcher.CheckAccess()方法,如果代码在UI线程上则返回true,如果在其他线程上则返回false。 典型的调用类似于:

 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( 

调用vs BeginInvoke
如果您希望当前线程等到UI线程处理了调度代码,则使用Invoke如果您希望当前线程继续而不等待UI线程上的操作完成,请使用BeginInvoke

MessageBox,Dispatchers和Invoke / BeginInvoke:
Dispatcher.Invoke将阻止您的线程,直到MessageBox被解除。
Dispatcher.BeginInvoke将允许您的线程代码继续执行,而UI线程将阻止MessageBox调用,直到它被解除。

CurrentDispatcher与Current.Dispatcher!
Dispatcher.CurrentDispatcher软件,因为我对此的理解是将返回当前线程而不是UI线程的Dispatcher。 通常,您对UI线程上的调度Application.Current.Dispatcher感兴趣 – 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"); }); }