如何使用进度条进行耗时的简单功能

时间:2015-02-16 07:04:56

标签: c# winforms progress-bar

我有一个没有任何for循环的简单函数。但是这个功能需要很长时间才能完成。所以我需要一个进度条来显示进程运行时。我见过的所有例子都有一个for循环,它会增加进度条。不幸的是,我没有for循环。这是我的代码:

//Form1.cs
 private void button1_Click(object sender, EventArgs e)
 {
    Connection cConnection = new Connection();
    textBox2.Text = cConnection.connect();  
 }

 //Program.cs
  public class Connection
    {
        public string connect()
        {
            try
            {


                System.Diagnostics.Process process = new System.Diagnostics.Process();
                System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
                startInfo.FileName = "cmd.exe";
                string command = "dir /s /b /o:gn";
                startInfo.Arguments = command; // this will take a quit long time to complete
                process.StartInfo = startInfo;
                return "Done"
            }
            catch(Exception e)
            {
                return "";
            }

        }
    }

我正在做的就是在命令提示符中执行命令,这需要很长时间才能完成。如何更新进度条

3 个答案:

答案 0 :(得分:4)

您不仅没有循环,也没有可用的活动。 dir没有针对您的计划的反馈机制。

这使您无法以任何准确度更新进度条。

如果您希望重新实现dir功能(例如在C#中),您可以让您的实现提供一种近似于实际进度的反馈机制。例如,如果顶级目录包含10个子目录,则可以在每个子目录完成处理时将进度条更新10%。这不完全准确,但与没有进展更新相比,这将是一个进步。

答案 1 :(得分:0)

我将提出一种解决方案,但从我的角度来看,这不是一个好主意。由于我们没有来自dir的反馈,我们可以按如下方式使用计时器。

public partial class Form1 : Form
{

    System.Windows.Forms.Timer t1 = new System.Windows.Forms.Timer();
    int counter = 0;

    public Form1()
    {
        InitializeComponent();
        backgroundWorker1.WorkerReportsProgress = true;
        backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
        backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
        backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
        t1.Interval = 1000;
    }

    void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        progressBar1.Value = 100;
        textBox1.Text = "Done";
    }

    private void button1_Click(object sender, EventArgs e)
    {
        backgroundWorker1.RunWorkerAsync();
        t1.Start();
    }

    void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {
            t1.Tick += new EventHandler(t1_Tick);
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.FileName = "cmd.exe";
            string command = "dir /s /b /o:gn";
            startInfo.Arguments = command; // this will take a quit long time to complete
            process.StartInfo = startInfo;              
            t1.Stop();
        }
        catch (Exception)
        {

        }
    }

    void t1_Tick(object sender, EventArgs e)
    {
        counter = counter + 10;
        backgroundWorker1.ReportProgress(counter);
    }

    void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        if (e.ProgressPercentage <= 90)
            progressBar1.Value = e.ProgressPercentage;
    }

}

答案 2 :(得分:0)

我知道这个问题已经很老了,但我遇到了类似的问题,以后可能会帮助其他人。正如我上面的其他人所说,您可以创建一个进度条,但是估计某个过程的时间既困难又耗时,而且很容易不准确。但是,如果您不必使用进度条,而只是想通知用户程序需要更长的时间来执行某个进程,那么您还有其他选择。

您可以使用加载指示器代替进度条,这样您就无需计算该过程所需的时间。本质上,您需要一个在后台循环播放的动画,而不是进度条。

This article 详细解释了如何构建加载指示器,您可能会发现它很有帮助。