我是C#.NET的新手。我尝试从主 UI 创建一个带有进度栏的表单以显示进度。我使用BackgroundWorker 来调用它。我可以显示进度对话框,但不能更新进度条值。请在下面找到代码。
主界面 :
namespace GC
{
public partial class MainUI : Form
{
private ProgressBar oProgressBar;
public MainUI()
{
InitializeComponent();
}
private void runButton_Click(object sender, EventArgs e)
{
oProgressBar = new ProgressBar();
backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
backgroundWorker1.RunWorkerAsync();
oProgressBar.ShowDialog();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
//some work here
for (int i = 0; i < 20; i++)
backgroundWorker1.ReportProgress(i);
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
oProgressBar.Close();
}
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
oProgressBar.progressBar1.Value = e.ProgressPercentage;
}
}
}
进度栏 UI 此窗体包含一个进度条
namespace GC
{
public partial class ProgressBar : Form
{
public ProgressBar()
{
InitializeComponent();
}
}
}
根据您提供的信息,有几件事可能是问题所在,但这取决于您遇到的行为:
方案 1:进度栏窗体在看到任何更新之前关闭
问题是您在进度条更新后几乎立即关闭表单。这将发生得如此之快,以至于您将没有时间看到进度条更新。
方案 2:进度栏窗体保持打开状态,并且栏永远不会更新
这对我来说表明您的"Do Work"代码中存在错误,该错误阻止了ReportProgress
函数被调用。为了检查这一点,我建议使用调试器逐步执行代码。
你应该做什么
如果毫无意义,则像示例中一样更新 for 循环中的进度条。您的示例将导致进度条立即跳转到 20% 并保持在那里。您应该在执行工作过程的每个"步骤"之后递增进度条。此外,重要的是,您的任务实际上需要一些时间来执行(alteast 一秒钟(,以便有时间显示某些内容。
例如,如果您的任务是从数据库中读取记录,那么例如,您可以在读取每一行后报告进度。我还建议您将其全部包装在 try catch 中并提醒任何错误(只是为了知道,以便您可以调试您的问题(......
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
try
{
//Do Stuff: e.g. read from DB
var tasks = GetTasks();
int i = 0;
double percentageIncrease = 100d / tasks.Count();
foreach(var task in tasks)
{
//do something for this task
backgroundWorker1.ReportProgress((int)(percentageIncrease * i));
i++;
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK);
}
}
看起来不错,
我认为你的问题更像是:
窗口在您看到它填满之前关闭,因为:
o进度条.关闭((;
正如 musefan 所说,您的酒吧只填满了 20%,这是正常的,因为:
for (int i = 0; i <20; i++( 背景工人1.报告进度(i(;
如果你想看到它完全填充,请使用 for 循环到 100:for (int i = 0; i <100; i++(
表单线程上调用更新吗?
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if(InvokeRequired)
{
Invoke(new EventHandler<ProgressChangedEvent>(backgroundWorker1_ProgressChanged), sender, e);
}
else
oProgressBar.progressBar1.Value = e.ProgressPercentage;
}