BackgroundWorker停止刷新WPF UI
本文关键字:WPF UI 刷新 BackgroundWorker | 更新日期: 2023-09-27 18:03:14
前段时间,我用基于wpf的UI编写了一个使用BackgroundWorker的简单应用程序:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerAsync();
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
LoadTextBlock.Visibility = Visibility.Hidden;
if (e.Error == null)
{
foreach (TechNews news in (e.Result as List<TechNews>))
{
NewsListBox.Items.Add(news);
}
}
else
{
MessageBox.Show(e.Error.Message, "Error");
}
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
CNetTechNewsParser parser = new CNetTechNewsParser();
parser.Parse();
e.Result = parser.News;
}
}
那时候效果很好。但是现在我再次启动它,发现UI停止刷新,即LoadTextBlock没有消失,新闻没有显示在列表框中。它只有在我最小化应用程序后才会刷新。
我从DoWork中删除了所有解析功能,但得到了相同的效果。然后注释RunWorkerAsync, UI开始正常工作。所以我认为问题是由后台工作人员引起的。但我不明白它有什么问题?
谢谢
我有点困惑,没有抛出无效的跨线程错误(UnauthorizedAccessException),但是尽管如此,您可以使用扩展方法在目标控件的正确调度程序上调用UI Update逻辑。
public static class WindowExtensions
{
public static void Dispatch(this Control control, Action action)
{
if (control.Dispatcher.CheckAccess())
action();
else
control.Dispatcher.BeginInvoke(action);
}
}
在你的例子中,用法是这样的:
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Dispatch(() =>
{
LoadTextBlock.Visibility = Visibility.Hidden;
if (e.Error == null)
{
foreach (TechNews news in (e.Result as List<TechNews>))
{
NewsListBox.Items.Add(news);
}
}
else
{
MessageBox.Show(e.Error.Message, "Error");
}
});
}