Update progress bar in another form while task is running

前端 未结 3 807
盖世英雄少女心
盖世英雄少女心 2021-02-02 04:41

**Ultimately I am going to have four tasks running concurrently and have another form that contains four progress bars. I would like for each progress bar to update as it\'s wo

相关标签:
3条回答
  • 2021-02-02 05:11

    Create your progress bar form on the main UI thread of the parent form, then call the Show() method on the object in your button click event.

    Here's an example with 2 bars:

    //In parent form ...
    private MyProgressBarForm progressBarForm = new MyProgressBarForm();
    
    private void button1_Click(object sender, EventArgs e)
    {
        progressBarForm.Show();
        Task task = new Task(RunComparisons);
        task.Start();
    }
    
    private void RunComparisons()
    {
        for (int i = 1; i < 100; i++)
        {
            System.Threading.Thread.Sleep(50);
            progressBarForm.UpdateProgressBar(1, i);
        }
    }
    
    //In MyProgressBarForm ...
    public void UpdateProgressBar(int index, int value)
    {
        this.Invoke((MethodInvoker) delegate{
            if (index == 1)
            {
                progressBar1.Value = value;
            }
            else
            {
                progressBar2.Value = value;
            }
        });
    }
    
    0 讨论(0)
  • 2021-02-02 05:12

    The TPL adds the IProgress interface for updating the UI with the progress of a long running non-UI operation.

    All you need to do is create a Progress instance in your UI with instructions on how to update it with progress, and then pass it to your worker which can report progress through it.

    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;
        }
    }
    

    This lets the Progress Form handle displaying progress to the UI, the working code to only handle doing the work, the main form to simply create the progress form, start the work, and close the form when done, and it leaves all of the work of keeping track of progress and marhsaling through the UI thread to Progress. It also avoids having multiple UI thread; your current approach of creating and manipulating UI components from non-UI threads creates a number of problems that complicates the code and makes it harder to maintain.

    0 讨论(0)
  • 2021-02-02 05:15

    .ShowDialog is a blocking call; execution won't continue until the dialog returns a result. You should probably look in to a BackgroundWorker to process the work on another thread and update the dialog.

    0 讨论(0)
提交回复
热议问题