我创建了一个表单,只要我调用一个耗时的例程,就会弹出并显示一个进度条。我通过UpdateProgress
方法提供了例程的进度。
我正在使用后台工作程序,允许用户在此表单更新时移动表单并继续开展业务。但是,表单只是锁定直到例程完成,然后快速将进度条斜坡上升到100%并退出(应该如此)。进度条应该imo随着对UpdateProgress
方法的调用进度而更新。
我在这里做错了什么?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace myNameSpace
{
public partial class ProgressIndicator : Form
{
int progressPercentage;
public ProgressIndicator()
{
InitializeComponent();
}
void progressUpdater_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// update the UI with appropriate fields
progressBar.Value = e.ProgressPercentage;
labelCommunicating.Text = "In progress: " + e.ProgressPercentage + "% complete";
}
void progressUpdater_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.Close();
}
void progressUpdater_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
while (true)
{
if (progressPercentage >= 100)
{
break;
}
worker.ReportProgress(progressPercentage);
Thread.Sleep(100);
}
}
public void UpdateProgress(int progressPercentage)
{
this.progressPercentage = progressPercentage;
}
private void ProgressIndicator_Load(object sender, EventArgs e)
{
BackgroundWorker progressUpdater = new BackgroundWorker();
progressUpdater.WorkerReportsProgress = true;
progressUpdater.WorkerSupportsCancellation = true;
progressUpdater.DoWork += new DoWorkEventHandler(progressUpdater_DoWork);
progressUpdater.RunWorkerCompleted += new RunWorkerCompletedEventHandler(progressUpdater_RunWorkerCompleted);
progressUpdater.ProgressChanged += new ProgressChangedEventHandler(progressUpdater_ProgressChanged);
progressUpdater.RunWorkerAsync();
}
}
}
答案 0 :(得分:1)
这闻起来像一个牵强附会的解决方案,我认为你的问题在于while loop
。但是,更好的方法可能是使用ProgressBar
简单地更新Invoke();
而不阻止用户界面,例如
Invoke(new myUpdate(updateProgress), pval);//call invoke whenever you need to update the progress bar assuming pval is an integer with the value to update with. This could be in a thread for instance.
//declare this as a class level delegate
private delegate void myUpdate(int progress);
//method to update progress bar
private void updateProgress(int progress)
{
progressBar.Value = progress;
}
答案 1 :(得分:0)
您可以这种方式创建流程,这样您就不需要围绕Invoke方法打包调用。
//delegate method
private delegate void updateProgressDelegate(int progress);
//actual method
private void updateProgress(int progress)
{
if(this.InvokeRequired)
{
this.Invoke(new updateProgressDelegate(updateProgress), progress);
}
else
{
progressBar.value = progress;
}
}