c#progressbar没有更新 [英] c# progressbar not updating

查看:35
本文介绍了c#progressbar没有更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 ProgressBarWindow,它有一个进度条和一个取消按钮,我用来报告文件 I/O 的进度.但是,尽管所有工作都在后台工作程序中完成,ProgressBarWindow 的 UI 线程和我的主窗口都挂起.进度条已呈现,就像我的主窗口一样,但在后台工作人员执行其操作时不会更新.在主窗口的构造函数的最后调用以下代码:

I have a ProgressBarWindow which has a progressbar and a cancel button on it which I use to report progress on file I/O. However, the UI Thread of the ProgressBarWindow and my main window both hang despite all the work being done in a backgroundworker. The progressbar is rendered, as is my main window, but does not update whilst the backgroundworker does its thing. The following code is called at the very end of the constructor of the main window:

iCountLogLinesProgressBar = new ProgressBarWindow();
iCountLogLinesProgressBar.cancelButton.Click += EventCountLogLinesProgressBarCancelButtonClicked;
iCountLogLinesProgressBar.Show();

iCountLogRecords = new BackgroundWorker();
iCountLogRecords.DoWork += EventCountLogLinesDoWork;
iCountLogRecords.ProgressChanged += EventCountLogLinesProgressChanged;
iCountLogRecords.RunWorkerCompleted += EventCountLogLinesRunWorkerCompleted;
iCountLogRecords.WorkerReportsProgress = true;
iCountLogRecords.WorkerSupportsCancellation = true;
iCountLogRecords.RunWorkerAsync(new BinaryReader(File.Open(iMainLogFilename, FileMode.Open, FileAccess.Read)));

EventCountLogLinesProgressChanged() 看起来像这样:

EventCountLogLinesProgressChanged() looks like this:

private void EventCountLogLinesProgressChanged(object sender, ProgressChangedEventArgs e)
{
    iCountLogLinesProgressBar.Value = e.ProgressPercentage;
}

这是 ProgressBarWindow 的简化版本(其余的只是几个 setter):

Here is a shortened version of ProgressBarWindow(the rest is just a couple of setters):

public partial class ProgressBarWindow : Window
{
    public ProgressBarWindow()
    {
        InitializeComponent();
        this.progressBar.Value = this.progressBar.Minimum = 0;
        this.progressBar.Maximum = 100;
    }

    public double Value
    {
        get
        {
            return progressBar.Value;
        }
        set
        {
            this.progressBar.Value = value;
        }
    }
} 

我已经尝试将 value setter 行包装在 dispatcher.invoke 委托中,但这给了我一个堆栈溢出(我不应该有一个 dispatcher.invoke 行,因为后台工作人员在 UI 线程中调用 ProgressChanged ,对吧?).我已经检查了 msdn 并用谷歌搜索,但我似乎找不到其他人有这个问题.

I've tried wrapping the value setter line in a dispatcher.invoke delegate but that gives me a stack overflow(I shouldn't have to have a dispatcher.invoke line anyway as backgroundworker calls ProgressChanged in the UI Thread, right?). I have checked msdn and googled but I can't seem to find anyone else with this problem.

编辑 抱歉,我没有意识到我的简化代码阻塞了 UI 线程,尽管使用了后台工作程序,但我得到了完全相同的行为,所以我错误地认为它们是等效的.我应该提到我正在使用后台工作人员:P

EDIT Apologies, I did not realise my simplified code blocked the UI Thread, I get exactly the same behaviour despite using a backgroundworker so I erroneously assumed they were equivalent. I should have mentioned I was using a backgroundworker :P

推荐答案

您正在阻塞 UI 线程,因此在循环完成之前它不会重新渲染 UI.

You're blocking the UI thread, so it won't re-render the UI until your loop has finished.

将后台处理移到单独的线程中,并使用适当的 Dispatcher 调用(或 BackgroundWorker)将 UI 更新调用编组回 UI 线程.

Move the background processing into a separate thread, and use appropriate Dispatcher calls (or BackgroundWorker) to marshal UI update calls back to the UI thread.

如果你的进度条真的只是一个计时器,你可以使用 Timer 类之一来更新它.

If your progress bar is really just meant to be a timer, you could use one of the Timer classes to update it.

好的,现在你已经改变了代码,我觉得没问题.它应该是线程安全的,因为您只是在 UI 线程上更改 UI.您的后台工作人员肯定会定期报告进度吗?

Okay, now you've changed the code, it looks okay to me. It should be thread-safe as you're only changing the UI on the UI thread. Is your background worker definitely reporting progress periodically?

这篇关于c#progressbar没有更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆