后台工作程序中的进度条获取在主线程中更新的参数 c# wpf

progress bar in background worker get argument which being updated in the main thread c# wpf

我有主线程,它是 WPF 中的向导。

用户完成设置向导的属性后,它会处理数据。

这需要几秒钟,我想提出一个报告进度的进度条。

因此,我总是在主线程变量调用 currentStep 上设置。

我的 thresholdStep 步数总共等于 12。

所以我希望进度条作为一个线程工作,但它也将通过使用 currentStep 变量连接到主线程。

所以,我被后台工作者这样使用:

public partial class MessageWithProgressBar : Window
{
    private BackgroundWorker backgroundWorker = new BackgroundWorker();
    public MessageWithProgressBar()
    {
        InitializeComponent();
        backgroundWorker.WorkerReportsProgress = true;
        backgroundWorker.ProgressChanged += ProgressChanged;
        backgroundWorker.DoWork += DoWork;
        backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
    }

    private void DoWork(object sender, DoWorkEventArgs e)
    {
        Thread.Sleep(100);
        int i = (int)e.Argument;
        backgroundWorker.ReportProgress((int)Math.Floor((decimal)(8*i)));
        if (i > GeneralProperties.General.thresholdStep)
            backgroundWorker.ReportProgress(100);
    }

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

    private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        WindowMsg msg = new WindowMsg();
        msg.Show();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        if (backgroundWorker.IsBusy == false)
            backgroundWorker.RunWorkerAsync(GeneralProperties.General.currentStep);
    }
}

此外,我从主线程调用了后台工作程序如下:

MessageWithProgressBar progress = new MessageWithProgressBar();
progress.Show();

实际发生的是 DoWork 仅在 currentStep = 1 时调用一次,并且它不会相对于主线程进行更新,主线程也会根据其进度更新 currentStep。

有什么解决办法吗?

谢谢!

更改您的 DoWork 方法,如下所示:

 private void DoWork(object sender, DoWorkEventArgs e)
    {
        Thread.Sleep(100);
        int i = (int)e.Argument;
        do
        {   
            i = GeneralProperties.General.currentStep;
            backgroundWorker.ReportProgress((int)Math.Floor((decimal)(8 * i)));
            if (i > GeneralProperties.General.thresholdStep)
               backgroundWorker.ReportProgress(100);
        }
        while (i < GeneralProperties.General.thresholdStep);
    }

只要确保您没有遇到 GeneralProperties.General 对象的线程 synchronization 问题,如果您在访问对象时使用 lock

更新:

更新问题:

 private void ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
        {
            progress.Value = e.ProgressPercentage;
        }), null);
    }