在任务运行时以另一种形式更新进度条

Uma*_*ker 2 c# winforms c#-5.0

**最终,我将同时运行四个任务,并有另一个包含四个进度条的表单.我希望每个进度条都能更新,因为它的工作任务正在完成.

这就是我要为初学者做的事情.

我有一个表格上有一些按钮.当我点击一个我正在创建一个新任务来做一些工作.

public partial class MyMainForm : Form
{

    private void btn_doWork_Click(object sender, EventArgs e)
    {
        Task task = new Task(RunComparisons);
        task.Start();
    }

    private void RunComparisons()
    {
        int progressBarValue = 0;
        MyProgressBarForm pBar = new MyProgressBarForm(maxValue, "some text");
        pBar.ShowDialog();
        foreach(string s in nodeCollection)
        {
            //do some work here
            progressBarValue++;
            pBar.updateProgressBar(progressBarValue, "some new text");
        }
        pBar.BeginInvoke(new Action(() => pBar.Close()));
    }
}
Run Code Online (Sandbox Code Playgroud)

在另一个包含带进度条的表单的类中:

public partial class MyProgressBarForm : Form
{
    public MyProgressBarForm(int maxValue, string textToDisplay)
    {
        InitializeComponent();
        MyProgressBarControl.Maximum = maxValue;
        myLabel.Text = textToDisplay;
    }

    public void updateProgressBar(int progress, string updatedTextToDisplay)
    {
        MyProgressBarForm.BeginInvoke(
            new Action(() =>
            {
                MyProgressBarControl.Value = progress;
                myLabel.Text = updatedTextToDisplay;
            }));
    }
Run Code Online (Sandbox Code Playgroud)

单击"执行"按钮时,将显示进度条表单但不会更新.它只是坐在那里挂起.如果我注释掉pBar.ShowDialog(); 然后进度条表单不显示,但要完成的工作完全运行完成.

当我创建自己的线程时,我完成了这项工作,但我读到了有关任务的内容,现在我正试图让它以这种方式运行.我哪里做错了?

Ser*_*rvy 15

TPL添加了IProgress用于更新UI的界面以及长时间运行的非UI操作的进度.

您需要做的就是Progress在UI中创建一个实例,其中包含如何使用进度更新它的说明,然后将其传递给可以通过它报告进度的工作人员.

public partial class MyMainForm : System.Windows.Forms.Form
{
    private async void btn_doWork_Click(object sender, EventArgs e)
    {
        MyProgressBarForm progressForm = new MyProgressBarForm();
        progressForm.Show();
        Progress<string> progress = new Progress<string>();
        progress.ProgressChanged += (_, text) =>
            progressForm.updateProgressBar(text);
        await Task.Run(() => RunComparisons(progress));
        progressForm.Close();
    }
    private void RunComparisons(IProgress<string> progress)
    {
        foreach (var s in nodeCollection)
        {
            Process(s);
            progress.Report("hello world");
        }
    }
}
public partial class MyProgressBarForm : System.Windows.Forms.Form
{
    public void updateProgressBar(string updatedTextToDisplay)
    {
        MyProgressBarControl.Value++;
        myLabel.Text = updatedTextToDisplay;
    }
}
Run Code Online (Sandbox Code Playgroud)

这使得Progress Form处理显示UI的进度,工作代码只处理执行工作,主要表单简单地创建进度表单,启动工作,并在完成后关闭表单,它保留所有工作通过UI线程跟踪进度和marhsaling Progress.它还避免了多个UI线程; 您当前从非UI线程创建和操作UI组件的方法会产生许多问题,这些问题会使代码复杂化并使其难以维护.