C# - 带滚动条样式的ProgressBar
我想在带有滚动样式的窗体上添加一个ProgressBar,以显示用户正在进行的操作。在耗时的操作过程中,表单不会更新,因此ProgressBar也会“冻结”。C# - 带滚动条样式的ProgressBar
我已经检查了几篇关于BackgroundWorker的帖子,但在我的案例中操作不报告进度,这就是为什么我需要一个Marquee栏。
赞赏任何帮助或代码片段。
注:我需要使用.NET 4.0(对XP的支持),所以我不能使用Task.Run :(
button1_Click(object sender, EventArgs e)
{
progressBar1.Style = ProgressBarStyle.Marquee;
progressBar1.MarqueeAnimationSpeed = 50;
// INSERT TIME CONSUMING OPERATIONS HERE
// THAT DON'T REPORT PROGRESS
Thread.Sleep(10000);
progressBar1.MarqueeAnimationSpeed = 0;
progressBar1.Style = ProgressBarStyle.Blocks;
progressBar1.Value = progressBar1.Minimum;
}
我查了一下BackgroundWorker的几个职位,但在我的情况下, 操作不报告进度,这就是为什么我需要一个跑马灯吧。
您可以使用BackgroundWorker,只是不要使用它的“进度”部分。这两件事并不相互排斥......
例子:
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
progressBar1.Style = ProgressBarStyle.Marquee;
progressBar1.MarqueeAnimationSpeed = 50;
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += bw_DoWork;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
bw.RunWorkerAsync();
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
// INSERT TIME CONSUMING OPERATIONS HERE
// THAT DON'T REPORT PROGRESS
Thread.Sleep(10000);
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressBar1.MarqueeAnimationSpeed = 0;
progressBar1.Style = ProgressBarStyle.Blocks;
progressBar1.Value = progressBar1.Minimum;
button1.Enabled = true;
MessageBox.Show("Done!");
}
听起来不错!是否有可能从bw_RunWorkerCompleted访问所有表单控件? (所以它在同一个线程上运行?) button1.Enabled = true; MessageBox.Show(“Done!”); 这表明了这一点。 – dobragab
是的,你可以安全**从RunWorkerCompleted()事件中访问所有的控件,因为它已经被BackgroundWorker控件编组到主UI线程。如果将来使用'ProgressChanged()'事件也是如此。 –
你仍然需要在不同的线程运行耗时的工作。 ..你是在UI线程,这意味着UI没有机会做任何UI更新上运行它(因此冻结您见证)!
您应该考虑使用Task<>
代替BackgroundWorker
。
见mor。的https://msdn.microsoft.com/en-us/library/hh195051%28v=vs.110%29.aspx电子信息Task<>
。
如果您不能使用Task<>
,那么你应该恢复到BackgroundWorker
并使用WorkCompleted
情况下,停止选取框并移动程序到其下一步的操作。
谢谢,我会看看它。请注意,我无法使用Task.Run,正如我在编辑中提到的那样。是否有任何由.NET 4.0支持的替代方法? – dobragab
已解决。不过,我认为这是处理它的最不优雅的方式。
button1_Click(object sender, EventArgs e)
{
progressBar1.Style = ProgressBarStyle.Marquee;
progressBar1.MarqueeAnimationSpeed = 50;
Task task = Task.Factory.StartNew(() =>
{
// INSERT TIME CONSUMING OPERATIONS HERE
// THAT DON'T REPORT PROGRESS
Thread.Sleep(10000);
});
while (!task.IsCompleted)
{
Application.DoEvents();
Thread.Sleep(1);
}
progressBar1.MarqueeAnimationSpeed = 0;
progressBar1.Style = ProgressBarStyle.Blocks;
progressBar1.Value = progressBar1.Minimum;
}
这通常是一个**非常糟糕的主意,让你的点击处理程序像这样的轮询循环。 –
你知道迭代器的数量在您的消费过程的开始做些什么呢?在这种情况下,我可能会提出一些实施建议。 – Graffito
这不是一个迭代,更像是等待MySQL连接或LDAP响应。 – dobragab