在WPF应用程序中使用C#分派器 [英] Using the C# Dispatcher in WPF Applications

查看:101
本文介绍了在WPF应用程序中使用C#分派器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个聊天客户端,不确定如何使用dispatcher.所以问题是我有这样一种方法:

I'm building a chat client and am not 100% sure on how to use the dispatcher. So the question is I have a method as such:

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

我是否需要使用Dispatcher.Invoke替代(myGUI.chatBox... )中的语句?感谢您的帮助.

Do i need to surrond the statement within (myGUI.chatBox... ) with a Dispatcher.Invoke? I appreciate any help.

推荐答案

您的应用具有主UI线程(通常为ManagedThreadId==1).通常,在聊天应用程序中,您的事件将进入其他线程(专用套接字侦听线程或侦听代码中的线程池线程).如果要从发生其他事件的事件中更新UI,则必须使用分派器.有用的测试是Dispatcher.CheckAccess()方法,如果代码在UI线程上,则返回true;在其他线程上,则返回false.一个典型的呼叫看起来像:

Your app has a main UI thread (usually ManagedThreadId==1). Typically in a chat app your events will come in on other threads (either dedicated socket listen threads or thread pool threads from listening code). If you want to update the UI from an event that gets pull on some other thread you must use the dispatcher. A useful test here is the Dispatcher.CheckAccess() method that returns true if code is on UI thread and false if on some other thread. A typical call looks something like:

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));
    }));
}

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

If you're in the main window you can use:

Dispatcher.BeginInvoke(...

如果您处于其他环境(例如视图模型)中,请使用:

If you're in someother context eg a view model then use:

Application.Current.Dispatcher.BeginInvoke(  

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

Invoke vs BeginInvoke
Use Invoke if you want the current thread to wait until the UI thread has processed the dispatch code or BeginInvoke if you want current thread to continue without waiting for operation to complete on UI thread.

消息框,调度程序和调用/开始调用:
Dispatcher.Invoke将阻塞您的线程,直到关闭MessageBox.
Dispatcher.BeginInvoke将允许您的线程代码继续执行,而UI线程将阻塞MessageBox调用,直到被取消.

MessageBox, Dispatchers and Invoke/BeginInvoke:
Dispatcher.Invoke will block your thread until the MessageBox is dismissed.
Dispatcher.BeginInvoke will allow your thread code to continue to execute while the UI thread will block on the MessageBox call until its dismissed.

CurrentDispatcher与Current.Dispatcher!
请注意Dispatcher.CurrentDispatcher,因为我对此的理解是,它将为当前线程而不是UI线程返回一个Dispatcher.通常,您是否对UI线程上的调度程序感兴趣-Application.Current.Dispatcher总是返回此值.

CurrentDispatcher vs Current.Dispatcher!
Be ware of Dispatcher.CurrentDispatcher as my understanding of this is that is will return a Dispatcher for the current thread not the UI thread. Generally are you interested in the dispatcher on the UI thread - Application.Current.Dispatcher always returns this.

附加说明:
如果发现经常需要检查调度程序CheckAccess,则有用的帮助程序方法是:

Additional note:
If you are finding you are having to check dispatcher CheckAccess often then a useful helper method is:

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));
});

这篇关于在WPF应用程序中使用C#分派器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆