在 WPF 应用程序中使用 C# 调度程序 [英] Using the C# Dispatcher in WPF Applications

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

问题描述

我正在构建一个聊天客户端,但我不是 100% 确定如何使用 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() + "
");
}

我是否需要用 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(  

调用与开始调用
如果希望当前线程等待 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.

MessageBox、Dispatchers 和 Invoke/BeginInvoke:
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天全站免登陆