进度条- c# -带有选框样式的进度条
本文关键字:样式 | 更新日期: 2023-09-27 18:02:09
我想添加一个窗体上的选框样式的进度条,以显示用户的东西正在进行中。在耗时的操作中,表单不会得到更新,因此进度条也会"冻结"。
我已经检查了几个关于BackgroundWorker的帖子,但在我的情况下,操作不报告进度,这就是为什么我需要一个选框栏。
感谢任何帮助或代码片段。
注意:我需要使用。net 4.0(为XP支持),所以我不能使用任务。:运行(
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,只是不要使用它的"progress"部分。这两件事并不相互排斥……
的例子:
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!");
}
您仍然需要在不同的线程上运行您耗时的工作…你在UI线程上运行它,这意味着UI没有机会进行任何UI更新(因此你会看到冻结)!
你应该考虑使用Task<>
而不是BackgroundWorker
。
参见https://msdn.microsoft.com/en-us/library/hh195051%28v=vs.110%29.aspx获取Task<>
的更多信息。
如果你不能使用Task<>
,那么你应该恢复到BackgroundWorker
,并使用WorkCompleted
事件来停止选框,并将你的程序移动到下一个操作。
解决。然而,我认为这是最不优雅的处理方式。
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;
}
首选解决方案
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
progressBar1.Style = ProgressBarStyle.Marquee;
progressBar1.MarqueeAnimationSpeed = 50;
Task.Factory.StartNew(() => {
// INSERT TIME CONSUMING OPERATIONS HERE
// THAT DON'T REPORT PROGRESS
Thread.Sleep(10000);
}, TaskCreationOptions.LongRunning).
ContinueWith(t => {
progressBar1.MarqueeAnimationSpeed = 0;
progressBar1.Style = ProgressBarStyle.Blocks;
progressBar1.Value = progressBar1.Minimum;
button1.Enabled = true;
MessageBox.Show("Done!");
}, TaskScheduler.FromCurrentSynchronizationContext());
}
注:为了处理可能的操作取消,示例实例化了一个CancellationTokenSource
对象,该对象生成一个取消令牌。