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开始正常工作。所以我认为问题是由后台工作人员引起的。但我不明白它有什么问题?

谢谢

BackgroundWorker停止刷新WPF 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");
        }
    });
}