Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# BackgroundWorker停止要刷新的WPF UI_C#_.net_Wpf_Backgroundworker - Fatal编程技术网

C# BackgroundWorker停止要刷新的WPF UI

C# BackgroundWorker停止要刷新的WPF UI,c#,.net,wpf,backgroundworker,C#,.net,Wpf,Backgroundworker,不久前,我使用基于WPF的UI编写了一个简单的应用程序,它使用BackgroundWorker: public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { BackgroundW

不久前,我使用基于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;
    }
}
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
}
已加载私有无效窗口(对象发送器、路由目标)
{
BackgroundWorker工人=新的BackgroundWorker();
worker.DoWork+=新的doworkereventhandler(worker\u DoWork);
worker.RunWorkerCompleted+=新的RunWorkerCompletedEventHandler(worker\u RunWorkerCompleted);
worker.RunWorkerAsync();
}
私有void worker\u RunWorkerCompleted(对象发送方,RunWorkerCompletedEventArgs e)
{
LoadTextBlock.Visibility=可见性.Hidden;
如果(e.Error==null)
{
foreach(TechNews中的新闻(例如,结果作为列表))
{
NewsListBox.Items.Add(新闻);
}
}
其他的
{
MessageBox.Show(例如Error.Message,“Error”);
}
}
私有void worker_DoWork(对象发送方,DoWorkEventArgs e)
{
CNetTechNewsParser=新的CNetTechNewsParser();
parser.Parse();
e、 结果=parser.News;
}
}
当时它工作得很好。但现在我再次启动它,发现UI停止刷新,即LoadTextBlock不会消失,列表框中也不会显示新闻。只有在我最小化应用程序后,它才会刷新

我从DoWork中删除了所有解析功能,但得到了相同的效果。然后注释RunWorkerAsync,UI开始正常工作。所以我认为问题是由幕后工作人员造成的。但我不明白这是怎么回事


感谢

我有点困惑,没有抛出无效的跨线程错误(UnauthorizedAccessException),但是您可以使用扩展方法,在目标控件的正确调度程序上调用UI更新逻辑

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");
        }
    });
}
private void worker\u RunWorkerCompleted(对象发送方,runworkercompletedeventarge)
{
此。分派(()=>
{
LoadTextBlock.Visibility=可见性.Hidden;
如果(e.Error==null)
{
foreach(TechNews中的新闻(例如,结果作为列表))
{
NewsListBox.Items.Add(新闻);
}
}
其他的
{
MessageBox.Show(例如Error.Message,“Error”);
}
});
}

worker\u RunWorkerCompleted函数的线程上下文是什么?此函数可能执行不正确的跨线程操作。尝试Dispatcher.BeginInvoke进行UI更新,而不是直接控制访问。@AlexFarber尝试了Dispatcher.Invoke,但之前没有成功。现在试一下你的变体,瞧,它起作用了!但更有趣的是,我再次尝试了直接访问——现在它也能工作了!那很神秘。。。无论如何,谢谢你的回答,问题看起来已经解决了。据我所知,RunWorkerCompleted事件处理程序是由创建BackgroundWorker的线程运行的,在我的例子中是UI线程,因此不需要跨线程操作。后台线程运行DoWork事件处理程序,创建控件的线程运行ProgressChanged和RunWorkerCompleted事件处理程序