如何判断进度条何时完成?

时间:2015-02-11 16:18:28

标签: c#

我正在使用C#和WinForms。我正在更新progressBar。当Value达到它的最大值时,我希望它显示一个messageBox。

无论如何,progressBar在它满了时执行一个方法吗?那么一些代码示例或解决方案的链接将不胜感激

   private void BackgroundWorkerProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        //throw new NotImplementedException();
    }

    private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
    {


    }

    // Back on the 'UI' thread so we can update the progress bar - and our label :)
    void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        // The progress percentage is a property of e
        int percentComplete = progressBarStatus.Value / progressBarStatus.Maximum;
        labelPercentComplete.Text = percentComplete.ToString() + "% Completed";

        //progressBarStatus.Value = e.ProgressPercentage;
        //labelPercentComplete.Text = String.Format("Trade{0}", e.ProgressPercentage);
    } 

    private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if(progressBarStatus.Value == progressBarStatus.Maximum)
        {
            MessageBox.Show("Test");
        }
    }


 public void Form1_Load(object sender, EventArgs e)
 {

backgroundWorker1.DoWork += new DoWorkEventHandler(bgWorker_DoWork);
            backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler
                            (bgWorker_RunWorkerCompleted);
            backgroundWorker1.ProgressChanged += BackgroundWorkerProgressChanged;
 }

3 个答案:

答案 0 :(得分:3)

当后台工作程序完成时你似乎不想做某事,但是当进度条达到最大值时你想要做某事......好吧,首先,设置你的progressBarStatus最大值,然后你应该尝试这样的事情:

    void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        if (progressBarStatus.Maximum == e.ProgressPercentage)
        {
            // do whatever you want to do
        }
    } 

并从另一个表单更新progressBarStatus值。 尽管这可能不是最好的做事方式,如果这真的是你想要的,那么做任何让你开心的事情...... :)

编辑: 好的,我添加了完美的程序的完整示例,调用ProgressChanged事件,并正确检查Maximum值,当达到Maximum值时,ProgressBar重新启动并在Output窗口中打印消息,评论(当然还有一堆错别字:D),请尝试这个例子,看看它是如何工作的,并将其应用到你的问题中。

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

namespace BGWORKERAPP
{
    public partial class Form1 : Form
    {

        BackgroundWorker bgWorker = new BackgroundWorker();
        public Form1()
        {
            InitializeComponent();
            bgWorker.DoWork += bw_DoWork;
            bgWorker.WorkerReportsProgress = true;        // needed to be able to report progress
            bgWorker.WorkerSupportsCancellation = true;   // needed to be able to stop the thread using CancelAsync();
            bgWorker.ProgressChanged += bw_ProgressChanged;
            bgWorker.RunWorkerCompleted += bw_RunWorkerCompleted;

            // ProgressBar is added to the form manually, and here I am just setting some initial values
            progressBarStatus.Maximum = 100;
            progressBarStatus.Minimum = 0;
            progressBarStatus.Value = 0;
            progressBarStatus.Step = 10;
        }
        void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            int i = 0;
            while (true)    // keep looping until user presses the "Stop" button
            {
                if (bgWorker.CancellationPending)   // if bgWorker.CancelAsync() is called, this CancelationPending token will be set,
                {                                   // and if statement will be true
                    bgWorker.CancelAsync();
                    return;     // Thread is getting canceled, RunWorkerCompleted will be called next
                }

                i++;    // add any value you want, I chose this value because of the test example...
                Thread.Sleep(1);    // give thread some time to report (1ms is enough for this example) - NECESSARY, 
                                    //WITHOUT THIS LINE, THE MAIN THREAD WILL BE BLOCKED!
                bgWorker.ReportProgress(i); // report progress (will call bw_ProgressChanged) - NECESSARY TO REPORT PROGRESS!
            }
        }
        int somethingTerrible = 1;  // used to do something terrible ;)
        void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // I added this "somethingTerrible" variable to make the ProgressChanged run all over again, even when e.ProgressPercentage value
            // is greater then the progressBarStatus.Maximum, but, you should call bw.CancelAsync() because the job should be finished.
            // Also, this code will give you Exception eventually, numbers are limited after all...
            if (somethingTerrible * progressBarStatus.Maximum == e.ProgressPercentage)
            {
                Debug.WriteLine("THIS IS CALLED WHEN THE MAXIMUM IS REACHED");   // this will be printed in the Output window
                progressBarStatus.Value = 0; // progressBarStatus value is at the maximum, restart it (or Exception will be thrown)

                //bw.CancelAsync();   // used to stop the thread when e.ProgressPercentage is equal to progressBarMaximum, but in our
                                      // example, we just make the code keep running.
                                      // We should cancel bgWorker now because the work is completed and e.ProgressPercentage will
                                      // be greater then the value of the progressBarStatus.Maximum, but if you really want
                                      // you can do something like this to make the thread keep reporting without any errors (until numbers reach the limit)...
                somethingTerrible++;
            }
            else
            {
                progressBarStatus.Value++;  // increasing progressBarStatus.Value, until we get to the maximum.
            }
        }
        void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            MessageBox.Show("Worker completed");    // worker finished the task...
        }

        // Buttons are added to the Form manually as well
        private void runBgTask_Click(object sender, EventArgs e)    // button on the Form to start the thread
        {
            bgWorker.RunWorkerAsync();  // start the background worker (call DoWork)
        }

        private void stopBgTask_Click(object sender, EventArgs e)   // button on the Form to stop the thread
        {
            bgWorker.CancelAsync(); // tell the background worker to stop (will NOT stop the thread immediately); the DoWork will be
                                    // called once again, but with CancelationPending token set to true, so the if statement
                                    // in the DoWork will be true and the thread will stop.
        }
    }
}

答案 1 :(得分:2)

我想你应该看看专门为此目的而制作的BackgroundWorker。完成工作后,您将获得Event RunWorkerCompleted。我给你一个工作的例子,你要复制很多文件。

BackgroundWorker bgWorker = new BackgroundWorker();
bgWorker.DoWork += BackgroundWorkerDoWork;
bgWorker.ProgressChanged += BackgroundWorkerProgressChanged;
bgWorker.RunWorkerCompleted += new BackgroundWorkerCompletedEventHandler
                (bgWorker_RunWorkerCompleted);

void StartWork()
{ 
 // Start BackGround Worker Thread 
  bgWorker.RunWorkerAsync();

}

void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
{
   //NOTE : DONT play with the UI thread here...
  // Do Whatever work you are doing and for which you need to show    progress bar
     CopyLotsOfFiles() // This is the function which is being run in the background
   e.Result = true;// Tell that you are done
}

void CopyLotsOfFiles()
{
  Int32 counter = 0;
  List<String> filestobeCopiedList = ...; // get List of files to be copied
  foreach (var file in filestobeCopiedList)
  {
       counter++;
      // Calculate percentage for Progress Bar
      Int32 percentage = (counter * 100) / filesCount;
      bgWorker.ReportProgress(percentage);

      // Files copy code goes here
  }
  bgWorker.ReportProgress(100);
}

void BackgroundWorkerProgressChanged(object sender, ProgressChangedEventArgs e)
{
  // Access Main UI Thread here
  progressBar1.Value = e.ProgressPercentage;
}

private void BackgroundWorkerCompletedEventHandler(object sender, RunWorkerCompletedEventArgs e)
{
   //Always check e.Cancelled and e.Error before checking e.Result!
   //even though I'm skipping that here
  var operationSuccessFul = Convert.ToBoolean(e.Result);
  if(operationSuccessFul)
   MessageBox.Show("I am Done");
}

完成后,您将在BackgroundWorkerCompletedEventHandler函数中进行调用。您应该在BackgroundWorkerProgressChanged事件处理程序

中显示进度条

答案 2 :(得分:1)

你应该反思:创建一个中心&#34; Progress类&#34;。本课程负责:

  1. 更新进度条
  2. 如果符合某些条件,则显示MessageBox
  3. 或者换句话说:它不是进度条的响应性......除了显示进度之外还做其他事情。