C# WPF-ProgressBar仅在流程完成之前更新

C# WPF-ProgressBar仅在流程完成之前更新,c#,wpf,progress-bar,C#,Wpf,Progress Bar,我正在尝试使用ProgressBar,这对我来说是新的(只有异步可能?) 我跟着这条路走,没有遇到任何问题。我只是把代码再次放在这里 public partial class ProgressBarTaskOnWorkerThread : Window { public ProgressBarTaskOnWorkerThread() { InitializeComponent(); } private void Window_ContentRen

我正在尝试使用ProgressBar,这对我来说是新的(只有异步可能?)

我跟着这条路走,没有遇到任何问题。我只是把代码再次放在这里

public partial class ProgressBarTaskOnWorkerThread : Window
{
    public ProgressBarTaskOnWorkerThread()
    {
        InitializeComponent();
    }

    private void Window_ContentRendered(object sender, EventArgs e)
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.WorkerReportsProgress = true;
        worker.DoWork += worker_DoWork;
        worker.ProgressChanged += worker_ProgressChanged;

        worker.RunWorkerAsync();
    }

    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        for(int i = 0; i < 100; i++)
        {
            (sender as BackgroundWorker).ReportProgress(i);
            Thread.Sleep(100);
        }
    }

    void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        pbStatus.Value = e.ProgressPercentage;
    }
}
在我的代码中,我导入了一个文件列表,因此我将此.ValueProgress设置为0,然后每次导入文件时,我都执行此操作。ValueProgress=100*NumberImportedFiles/TotalFiles

在调试中,我还注意到我的
worker\u ProgressChanged
函数在导入时不工作(但是
worker\u DoWork
工作正常)。然后,只有在导入所有文件时,才会多次启动
worker\u ProgressChanged
(似乎只是一次触发所有已完成的更改)

编辑:刚刚做了另一个“愚蠢”的测试:

我保留了原始代码,添加了一个条件,因此在编辑ValueProgress后ProgressBar将开始移动:

void worker_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 0; i < 100; i++)
    {
        if(this.ValueProgress==0)
        {
            i--;
        }
        (sender as BackgroundWorker).ReportProgress(i);
        Thread.Sleep(100);
    }
}
void worker\u DoWork(对象发送方,DoWorkEventArgs e)
{
对于(int i=0;i<100;i++)
{
if(this.ValueProgress==0)
{
我--;
}
(发送方作为后台工作人员)。报告进度(i);
睡眠(100);
}
}

代码也不起作用,我的意思是,函数
worker\u DoWork
工作正常,进程开始后我开始增加,但进程栏没有移动(worker\u ProgressChanged没有启动)。

我没有评论的名声,所以我发布了一个答案。如果我的一些假设是错误的,我会提前道歉。您在哪里设置ValueProgress的值?如果您在UI线程上设置ValueProgress的值,而不是使用后台工作,则可能会挂起UI线程

如果是这种情况,则不会显示对进度条的任何更新。尝试在后台工作程序中执行任何更新,以保持UI可以自由更新


以下是有助于解决此问题的教程,您可以尝试在主线程上更新ProgressBar

void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    Application.Current.Dispatcher.Invoke(() => pbStatus.Value = e.ProgressPercentage);
}

问题是,在另一个线程上更新UI将不起作用。只有主线程可以。

在ReportProgress之前打印this.valueProgress的值-它正在更改/增加吗?@pratekshrivastava是的is@PrateekShrivastava谢谢,事实上问题是我不明白BackgroundWorker是如何工作的。在Arc2006回答之后,我可以通过阅读另一个教程来理解它。所以你是对的,我没有在后台工作中保存值进度,你能解释一下如何做到这一点吗?(到目前为止从未使用过异步函数)。刚找到一本关于
BackgroundWorker
的教程,我会先读一读,谢谢,我想我已经理解了你的传统意思,启动后台工作程序时,所有正在更改值的代码都应该放在分配给worker.DoWork的方法中——在本例中为worker\u DoWork。您可以在工作线程之外更改值,但在所有代码完成执行之前,UI不会反映更改。是的,我现在理解阅读教程(仍在上面),老实说,现在我不明白您的意思,但在阅读教程后,我想我会,似乎没有那么困难。如果我理解了教程,所有代码(导入文件)可能不在我的UI中,但在
worker\u DoWork
函数中?只能在异步模式下管理ProgesBar?
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    Application.Current.Dispatcher.Invoke(() => pbStatus.Value = e.ProgressPercentage);
}