我想显示在外部库中执行的计算进度。
例如,如果我有一些计算方法,并且想在Form类中将其用于100000个值,我可以编写:
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Caluculate(int i) { double pow = Math.Pow(i, i); } private void button1_Click(object sender, EventArgs e) { progressBar1.Maximum = 100000; progressBar1.Step = 1; for(int j = 0; j < 100000; j++) { Caluculate(j); progressBar1.PerformStep(); } } }
我应该在每次计算之后执行步骤。但是,如果我在外部方法中执行所有100000计算,该怎么办?如果我不想使此方法依赖进度条,什么时候应该“执行步骤”?例如,我可以写
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void CaluculateAll(System.Windows.Forms.ProgressBar progressBar) { progressBar.Maximum = 100000; progressBar.Step = 1; for(int j = 0; j < 100000; j++) { double pow = Math.Pow(j, j); //Calculation progressBar.PerformStep(); } } private void button1_Click(object sender, EventArgs e) { CaluculateAll(progressBar1); } }
但我不想那样做。
我建议您看看BackgroundWorker。如果WinForm中的循环如此之大,它将被阻塞,并且您的应用程序看起来像已经死机了。
查看BackgroundWorker.ReportProgress()以了解如何将进度报告回UI线程。
BackgroundWorker.ReportProgress()
例如:
private void Calculate(int i) { double pow = Math.Pow(i, i); } private void button1_Click(object sender, EventArgs e) { progressBar1.Maximum = 100; progressBar1.Step = 1; progressBar1.Value = 0; backgroundWorker.RunWorkerAsync(); } private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { var backgroundWorker = sender as BackgroundWorker; for (int j = 0; j < 100000; j++) { Calculate(j); backgroundWorker.ReportProgress((j * 100) / 100000); } } private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar1.Value = e.ProgressPercentage; } private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // TODO: do something with final calculation. }