如何在每个循环周期中一步更新进度条? C#

时间:2010-09-16 13:36:04

标签: c# .net multithreading progress-bar backgroundworker

在C#,windows窗体中创建.net应用程序。如何在100循环循环的每个循环中更新进度条1步? (我正在处理循环中的excel表。) 进度条控件位于UI类中,该类连接到连接到自定义类的控制器类 (MVC模式)。循环在自定义类中。 我是否需要在每种方法中一直向下发送UI类实例,还是有更好的方法?

现在,循环结束后进度条会更新。 Application.doevents和.update或.refresh不起作用。

3 个答案:

答案 0 :(得分:5)

说下面是你的班负责在其中完成循环的工作。添加事件以指示您的进度。然后从您的UI处理该事件并相应地更新进度条。

sealed class Looper
{
    public event EventHandler ProgressUpdated;

    private int _progress;
    public int Progress
    {
        get { return _progress; }
        private set
        {
            _progress = value;
            OnProgressUpdated();
        }
    }

    public void DoLoop()
    {
        _progress = 0;
        for (int i = 0; i < 100; ++i)
        {
            Thread.Sleep(100);
            Progress = i;
        }
    }

    private void OnProgressUpdated()
    {
        EventHandler handler = ProgressUpdated;
        if (handler != null)
        {
            handler(this, EventArgs.Empty);
        }
    }
}

您可以通过在用户界面中设置BackgroundWorker来实现此目的,在backgroundWorker.DoWork事件中,您可以调用looper.DoLoop()。然后在looper.ProgressUpdated事件的处理程序中,您可以调用backgroundWorker.ReportProgress从UI线程中增加进度条。

请注意,将进度本身包含在ProgressUpdated事件所包含的信息中可能更有意义(我只是想写出一个源自EventArgs的新类来说明这个;你可能还是得到了图片。

另请注意,除非您在UI线程的单独线程上使用循环执行代码,否则上述操作确实没有意义。否则,您的所有工作都会在下一次UI刷新之前完成,因此您的进度条不会提供任何值(当循环完成时,它将从0到100)。

只是一个如何实现这种事情的例子。

答案 1 :(得分:1)

我通常有一个类在UI上进行调用检查。 UI - &gt; “UpdaterClass” - &gt;其他课程。

Updater类具有预定义的方法和对UI控件的引用。所以Updater.StepProgressBar()就是我所说的步骤UI进度条。我将Updater类引用传递给任何需要直接更新UI的类。

这样,来自不同线程的所有UI更新都由一个类处理。不是最通用的方式来实现它,但它永远不会失败。

示例psuedocode:

class Updater()
{

  public ProgressBar pb;

  delegate void UpdateProgressBar();

  public StepProgressBar()
  {
     if(pb.InvokeRequired)
     {
          BeginInvoke(new UpdateProgressBar(this.StepProgressBar);
     }
     else
     {
          pb.Step();
      }
   }

}

这样的事情。

答案 2 :(得分:1)

您可以使用委托。当后台进程创建自定义类时,请绑定从自定义类调用以报告更新的委托。然后,您可以在UI层中对该调用做出反应,并从那里更新进度条。

e.g。 (警告,伪代码):

MyCustomClass class = new MyCustomClass();
class.ProgressUpdated += (s,e)=>{ /* update UI */};
class.StartLoop();