使用C#Dispatcher

Tom*_*890 22 c# wpf invoke dispatcher

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

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

我是否需要(myGUI.chatBox... )用一个Dispatcher.Invoke?我感谢任何帮助.

Ric*_*bob 81

您的应用有一个主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));
    }));
}
Run Code Online (Sandbox Code Playgroud)

如果您在主窗口中,则可以使用:

Dispatcher.BeginInvoke(...
Run Code Online (Sandbox Code Playgroud)

如果你在另一个上下文中,例如视图模型,那么使用:

Application.Current.Dispatcher.BeginInvoke(  
Run Code Online (Sandbox Code Playgroud)

调用VS BeginInvoke的
使用Invoke,如果你想在当前线程等待,直到UI线程处理,调度代码或者BeginInvoke,如果你想当前线程继续,而不必等待操作完成的UI线程.

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

CurrentDispatcher vs Current.Dispatcher!
是洁具Dispatcher.CurrentDispatcher作为我对此的理解是将返回调度当前线程不是UI线程.通常,您对UI线程上的调度程序感兴趣 - Application.Current.Dispatcher始终返回此信息.

附加说明:
如果您发现必须经常检查调度程序CheckAccess,那么一个有用的帮助方法是:

public void DispatchIfNecessary(Action action) {
    if (!Dispatcher.CheckAccess())
        Dispatcher.Invoke(action);
    else
        action.Invoke();
}
Run Code Online (Sandbox Code Playgroud)

可以称之为:

DispatchIfNecessary(() => {
    network_links.Add(new NetworkLinkVM(link, start_node, end_node));
});
Run Code Online (Sandbox Code Playgroud)

  • 再加上一票,因为您编写了可以帮助很多 C# 初学者的 `using` 指令。 (2认同)