在c#中使用进度条

时间:2015-07-13 11:10:02

标签: c#

我想在c#应用程序中显示进度条。有一个功能,我在我的应用程序中按下按钮,这是耗时的,并且无法确定完成整个过程需要多少时间,因为我正在从Excel工作表中读取数据并存储到数据库还有那些东西。

当我点击按钮时,进度条应显示正确的状态,当整个过程完成时,我想显示“已成功完成”的消息。

AlertForm

StartConversion()是我应用中的另一个表单,用于显示进度条 {{1}}方法是一种调用另一个方法的方法,该方法存在于实际执行耗时任务的类中。

我该如何完成这项任务?

3 个答案:

答案 0 :(得分:1)

通常使用BackgroundWorker

来完成

它在一个单独的线程中运行,并提供工具来实现两个要求(更新进度信息,并在操作完成时执行)。您只需要创建BackgroundWorker的实例并将其WorkerReportsProgress - 属性设置为true

然后只需订阅符合您需求的event

  1. DoWork - 执行实际的长时间运行任务
  2. ProgressChanged - 更新进度信息(例如,ProgressBar-value)
  3. RunWorkerCompleted - 显示您的成功消息
  4. 最后调用RunWorkerAsync - 方法,你就完成了。

    示例代码

    var demoWorker = new BackgroundWorker { WorkerReportsProgress = true };
    demoWorker.DoWork += (sender, args) =>
                {
                    var worker = sender as BackgroundWorker;
    
                    if (sender == null) throw new Exception("Not a BackgroundWorker!");
    
                    foreach (var VARIABLE in COLLECTION)
                    {
                        // do your work
    
                        worker.ReportProgress(progressPercentage); // invokes the workers ProgressChanged-event
                    }
                }
    
    demoWorker.ProgressChanged += (sender, args) =>
                {
                    this.progressBar.Value = args.ProgressPercentage;
                };    
    
    demoWorker.RunWorkerCompleted += (sender, args) =>
                {
                    // invoked when DoWork's eventhandler terminates
                    // show message
                };
    
    demoWorker.RunWorkerAsync(); // Invokes the workers DoWork-event
    

答案 1 :(得分:0)

您应该使用backgroundworker

图像以下场景:

您有一个大约有1000行要处理的Excel文件。对于进度条,您可以假设10行是百分比。

时不时地在后台工作者中让它与主线程进行通信,说明已经处理了多少百分比。

backgroundworker有一个事件可以用来不时地填充你的进度条:

例如:

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;

        var base = 100;
        var counter = ExcelRows.Count;
        var progressCounter = 0;
        for (int i = 1; i <= ExcelRows.Count; i++)
        {
            if (worker.CancellationPending == true)
            {
                e.Cancel = true;
                break;
            }
            else
            {
                // Perform a time consuming operation and report progress.
                //perform you action
                MyRow.Save();

                //report to the Progressbar
                if(i % counter == 0)
                     worker.ReportProgress(progressCounter++);
            }
        }
    }

    // This event handler updates the progress. 
    private void backgroundWorker1_ProgressChanged(object sender,           ProgressChangedEventArgs e)
    {
        MyProgress.Value = string.Format("{0}/100 %",e.ProgressPercentage);
    }

答案 2 :(得分:0)

这样的一种方法是使用不同的线程使用backgroundworker。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        InitializeBackgroundWorker();
    }

    private bool done = true;
    int percentComplete = 1;

    internal bool ImportData(IList<string> filenames)
    {
        try
        {
            // Long running task around 5 to 10 minutes

            return true;
        }
        catch (Exception ex)
        {
            // returning true to break from th display progress loop
            return true;
        }
    }

    private void InitializeBackgroundWorker()
    {
        backgroundWorker = new BackgroundWorker
        {
            WorkerReportsProgress = true,
            WorkerSupportsCancellation = true
        };
        backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
        backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);
        backgroundWorker.ProgressChanged +=new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);
    }

    private void button1_Click(System.Object sender,System.EventArgs e)
    {
        //fd is Browse dialog to select files in my case

        if (fd.ShowDialog() == DialogResult.OK)
        {
            var flist = fd.FileNames.ToList();                

            // Disable the Start button until the asynchronous operation is done.
            this.startButton.Enabled = false;

            if (!backgroundWorker.IsBusy)
            {
                this.Cursor = Cursors.WaitCursor;

                backgroundWorker.RunWorkerAsync(flist);
            }
            else
            {
                backgroundWorker.CancelAsync();
            }
        }
    }

    private void DisplayProgress(BackgroundWorker worker)
    {
        try
        {
            percentComplete = 1;

            while (done)
            {
                Thread.Sleep(500);
                // Report progress
                if (percentComplete == 100)
                    percentComplete = 1;
                worker.ReportProgress(++percentComplete);
            }
        }
        catch (Exception e)
        {

        }
    }

    // This event handler is where the actual,
    // potentially time-consuming work is done.
    private void backgroundWorker_DoWork(object sender,DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;

        if (worker.CancellationPending)
        {
            e.Cancel = true;
        }
        else
        {
            new Thread(() =>
            {
                DisplayProgress(worker);

            }).Start();

            done = ImportData((List<string>) e.Argument);

            worker.ReportProgress(100);

            e.Result = "Converted " + Path.GetFileName(((List<string>) e.Argument)[0]) + " successfully.";
        }
    }

    // This event handler deals with the results of the background operation.
    private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        // First, handle the case where an exception was thrown.
        if (e.Error != null)
        {
            MessageBox.Show(e.Error.Message);
        }
        else if (e.Cancelled)
        {
            // Next, handle the case where the user canceled
            // the operation.
            // Note that due to a race condition in
            // the DoWork event handler, the Cancelled
            // flag may not have been set, even though
            // CancelAsync was called.               
        }
        else
        {
            // Finally, handle the case where the operation succeeded.
            listView.Items.Add(new ListViewItem(Text = e.Result.ToString()));
            this.Cursor = Cursors.Arrow;
        }

        startButton.Text = "Start";
        startButton.Enabled = true;
    }

    // This event handler updates the progress bar.
    private void backgroundWorker_ProgressChanged(object sender,ProgressChangedEventArgs e)
    {
        this.progressBar.Value = e.ProgressPercentage;
    }
}