C#Winform ProgressBar和BackgroundWorker

use*_*312 15 c# backgroundworker winforms progress-bar

我有以下问题:

我有一个名为MainForm的表单.我在这张表格上进行了长时间的操作.

虽然这个长时间的操作正在进行,但我需要在MainForm之上显示另一个名为ProgressForm的操作.

ProgressForm包含一个进度条,需要在长时间操作时进行更新.

长操作完成后,应自动关闭ProgressForm.

我写了以下代码:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace ClassLibrary
{
    public class MyClass
    {
        public static string LongOperation()
        {
            Thread.Sleep(new TimeSpan(0,0,30));

            return "HelloWorld";
        }
    }
}

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace BackgroungWorker__HelloWorld
{
    public partial class ProgressForm : Form
    {
        public ProgressForm()
        {
            InitializeComponent();
        }

        public ProgressBar ProgressBar
        {
            get { return this.progressBar1; }
            set { this.progressBar1 = value; }
        }
    }
}

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using ClassLibrary;

namespace BackgroungWorker__HelloWorld
{
    public partial class MainForm : Form
    {
        ProgressForm f = new ProgressForm();

        public MainForm()
        {
            InitializeComponent();  
        }

        int count = 0;
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (f != null)
            {
                f.ProgressBar.Value = e.ProgressPercentage;
            }

            ++count;
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled) 
            {  
                MessageBox.Show("The task has been cancelled");  
            }  
            else if (e.Error != null)  
            {                  
                MessageBox.Show("Error. Details: " + (e.Error as Exception).ToString());  
            }  
            else 
            {  
                MessageBox.Show("The task has been completed. Results: " + e.Result.ToString());  
            }
        }


        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            if (f == null)
            {
                f = new ProgressForm();
            }

            f.ShowDialog();

            //backgroundWorker1.ReportProgress(100);

            MyClass.LongOperation();

            f.Close();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            backgroundWorker1.CancelAsync();

            this.Close();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我找不到更新的方法progressBar.

backgroundWorker1.ReportProgress()应该在哪里放置,我该如何称呼它?

我不能做任何改变,MyClass因为我不知道在我的应用程序的这一层中完成操作会发生什么或需要多长时间.

谁能帮我?

Jon*_*eet 12

一个问题是你睡了30秒.通常,您可以ReportProgress在长时间运行的任务中的各个点进行呼叫.因此,为了证明这一点,您可能希望将代码更改为休眠1秒钟,但需要30次 - ReportProgress每次完成睡眠时调用.

另一个问题是你ProgressForm 后台线程中显示你的.您应该在UI线程中启动它,但将后台工作程序的ProgressChanged事件挂钩到它.然后,当后台工作人员报告进度时,将更新进度表单.

  • 那么你无法准确报告进度.我的意思是你可以在`ProgressForm`中添加一个计时器,每秒只增加一个进度条,但这只会产生错觉.如果你无法找到*实际*进度,那么进度条有用吗? (6认同)