在C#中实现进度条的正确方法

我正在学习winforms,我为自己设定了一个简单的目标,即制作一个从空到满的进度条。 这是我的畸形尝试:

public partial class Form1 : Form { static BackgroundWorker bw = new BackgroundWorker(); public Form1() { InitializeComponent(); bw.DoWork += bw_DoWork; bw.RunWorkerAsync(); } void bw_DoWork(object sender, DoWorkEventArgs e) { for(int i=0; i<100; ++i) { progressBar1.PerformStep(); Thread.Sleep(10); } } } 

我很确定Thread.Sleep()是应该受到谴责的。 我怎么在这里避免它?

你已经做得差不多了。 BackgroundWorker具有用于报告进度的内置机制。

 public Form1() { bw1.WorkerReportsProgress = true; bw1.ProgressChanged += bw1_ProgressChanged; bw1.DoWork += bw1_DoWork; bw1.RunWorkerAsync(); } private void bw1_DoWork(object sender, DoWorkEventArgs e) { var worker = sender as BackgroundWorker; while (workNotDone) { //Do whatever work worker.ReportProgress(CalculateProgressDonePercentage()); } } private void bw1_ProgressChanged(object sender, ProgressChangedEventArgs e) { //This is called on GUI/main thread, so you can access the controls properly progressBar.Value = e.ProgressPercentage; } 

除非您当然只是尝试动画进度条而不实际报告任何进度,在这种情况下您应该只使用Marquee类型,它会自动滚动进度条而不做任何事情。 或者只使用Thread.Sleep()的后台线程。

在后台线程中,调用Thread.Sleep没有任何问题。
如果这是占位符,您可以安全地将其替换为实际工作。

但是,您无法直接从后台线程操作ProgressBar(或任何其他控件)。
相反,您应该使用BackgroundWorker的内置进度function来控制进度条。

如果你只是试图为无意义的progressbasr设置动画,你应该使用WinForms Timer而不是BackgroundWorker

如果您只是想在执行耗时的任务时测试更新UI,则Thread.Sleep是可以的。 对于非平凡的程序,您总会在这里找到一些任务。

但是,您不应直接在BackgroundWorker.DoWork更新进度条,因为Windows要求必须在UI线程上调用更新UI,而不是后台线程。 而是调用BackgroundWorker.ReportProgress方法。 始终更新BackgroundWorker.ProgressChanged事件中的UI。

你可以在这里看到这个例子: http : //msdn.microsoft.com/en-us/library/cc221403( v = vs.95) .aspx