如何使用后台线程中的信息更新WPF窗口?
我正在创建一个wpf应用程序,它在后面执行许多任务,但仍然需要UI响应并显示各种后台任务的状态。 它还可以选择不显示UI,在这种情况下,应该丢弃状态消息而根本不创建主窗体的实例。
我试图删除
StartupUri="MainWindow.xaml"
来自App.xaml。 然后,在App.xaml.cs中,我有
`
public App() { Startup += new StartupEventHandler(App_Startup); } void App_Startup(object sender, StartupEventArgs e) { // Code which loads application settings is here if (pf.ShowUI) { MainWindow mainWindow = new MainWindow(); mainWindow.Show(); } // The background processes will begin here. }`
如有必要,这将显示主窗体并启动所有后台进程。 这部分有效。
为了从后台向UI发送消息,我实现了一个非常基本的信使:
`
internal interface IMessageHandler { void ReceiveMessage(string message); } internal class Messenger { private static List _handlers; internal static void AddHandler(IMessageHandler handler) { _handlers.Add(handler); } internal static void RemoveHandler(IMessageHandler handler) { try { _handlers.Remove(handler); } catch (Exception ex) {} } internal static void Broadcast (string message) { foreach (IMessageHandler handler in _handlers) { handler.ReceiveMessage(message); } } }`
主窗体实现了IMessageHandler接口,并在启动时将自身添加到Messenger作为处理程序。 任何需要向主窗体发送状态的进程只需要调用messenger的Broadcast
方法。
我遇到的问题是,在后台进程完成之前,消息不会显示在表单上,并且UI也会被锁定。
处理接收消息的UI中的代码如下:
`
public void ReceiveMessage(string message) { Dispatcher.Invoke(DispatcherPriority.Normal, new Action(AddText), message); } private void AddText(string text) { Label myLabel = new Label(); myLabel.Content = text; stackPanel1.Children.Add(myLabel); if (stackPanel1.Children.Count > 5) { stackPanel1.Children.RemoveAt(0); } }`
为什么我的后台进程会冻结我的UI? 我该怎么做才能防止它? 为什么我的UI没有更新状态消息?
我有同样的问题, 这篇博文帮我解决了。
也许这是你的问题:
Dispatcher.Invoke(DispatcherPriority.Normal, new Action(AddText), message);
尝试将此更改为,
Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(AddText), message);
因为当您使用Invoke
,该方法将被执行并且应用程序等待它完成,但是使用BeginInvoke
该方法被Asychnronously调用,并且应用程序继续执行,同时执行BeginInvoke
引用的方法。
阅读: 是否使用Invoke或BeginInvoke
使用以下代码可以避免冻结UI。 在我的应用程序中,我使用了BackgroundWorker类。 通过使用代码更改表单上的任何内容,将引发运行时错误。
我使用下面的代码来避免这种情况,它对我来说非常适合。
Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate() { rtf_status.AppendText("Validating XML against schema...Please waitn"); }));
请注意大括号之间的部分('{}’)如果您希望更改表单上的内容,则应放置代码。
上述就是C#学习教程:如何使用后台线程中的信息更新WPF窗口?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1034403.html