2011-06-01 24 views
4

我正在學習winforms,併爲自己設定了一個簡單的目標,即讓進度條從空到滿。這裏是我的畸形嘗試:在C#中實現進度條的正確方法

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()是應該受到譴責的。我在這裏如何避免它?

+0

嘗試[這裏](http://stackoverflow.com/questions/2168192/progressbar-separate-thread)。或[這裏](http://stackoverflow.com/questions/1946377/c-progressbar-problem)。或[這裏](http://stackoverflow.com/questions/336553/how-to-display-progressbar-if-waithandle-is-used)。 – 2011-06-01 16:49:54

+0

或者如果你想做一些興奮嘗試運行一個算法,並使用StopWatch對象來衡量一個步驟從該算法,比你可以計算多少次步驟將被執行,所以你可以得到TotalTime,並基於該使用你'數學技能以獲得當前階段的百分比,所以我認爲這將滿足你是老師。 – Burimi 2011-06-01 21:51:56

回答

7

你已經在做它幾乎正確。 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()的後臺線程。

3

在後臺線程中,調用Thread.Sleep沒有任何問題。
如果這是一個佔位符,您可以安全地將其替換爲實際工作。

但是,您不能直接從後臺線程操縱ProgressBar(或任何其他控件)。
相反,您應該使用BackgroundWorker的內置進度功能來控制進度欄。

如果您只是想爲無意義的progressbasr設置動畫效果,則應該使用WinForms Timer而不是BackgroundWorker

1

如果你只是想做一個耗時的任務測試更新界面,Thread.Sleep沒問題。對於非平凡的程序,您總是會找到一些任務來完成。

但是,您不應該直接更新BackgroundWorker.DoWork中的進度條,因爲Windows要求必須在UI線程上調用更新UI,而不是後臺UI。相反,請撥打BackgroundWorker.ReportProgress方法。始終更新BackgroundWorker.ProgressChanged事件中的UI。

您couls在這裏看到的例子:http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx