我在WinForms中只有一点线程经验。我正在尝试将进度条设置为100,睡眠2秒,然后隐藏进度条。
我有:
public void ProgressBarTimerStop()
{
if (!AnyWorkersBusy())
{
if (InvokeRequired)
{
Invoke((MethodInvoker)delegate
{
ProgressBarTimer.Stop();
Thread.Sleep(1000);
Application.DoEvents();
Thread.Sleep(1000);
StatusToolStripProgressBar.Visible = false;
StatusToolStripProgressBar.Value = StatusToolStripProgressBar.Minimum;
});
}
else
{
ProgressBarTimer.Stop();
StatusToolStripProgressBar.Value = StatusToolStripProgressBar.Maximum;
Thread.Sleep(1000);
Application.DoEvents();
Thread.Sleep(1000);
StatusToolStripProgressBar.Visible = false;
StatusToolStripProgressBar.Value = StatusToolStripProgressBar.Minimum;
}
}
}
对于当前问题,我遇到的InvokeRequired为false。
当我拨打电话时:
StatusToolStripProgressBar.Value = StatusToolStripProgressBar.Maximum;
我的监视窗口显示设置的值,但GUI未更新以反映这一点。如果我立即睡了整整两秒钟,GUI就不会在睡觉前更新。
如果我事先调用Application.DoEvents()而没有调用sleep,它似乎什么也不做。
如果我睡觉,然后调用DoEvents - GUI更新,然后我回去睡觉。这是正确的,但我觉得我的代码很糟糕。
我在这里误解了一个关键概念吗?
编辑:仅通过“RunWorkerCompleted”事件处理程序调用ProgressBarTimerStop。
我尝试了这个,但它没有效果:
StatusToolStripProgressBar.GetCurrentParent().Refresh();
答案 0 :(得分:1)
您缺少的“关键概念”是更新进度条的值不会立即告诉进度条重绘自己。
更新进度条时,GUI线程重新绘制下一个窗口重绘的进度条。这只有在GUI线程可以自由执行时才会发生。通常,当窗口从操作系统接收到绘制消息时,会发生这种情况。这应由Application.DoEvents
选取,但可能是邮件排队的速度不够快,无法被DoEvents
选中。您可以通过Refresh
电话强制执行此操作。
答案 1 :(得分:0)
每一步都致电StatusToolStripProgressBar.ProgressBar.Refresh();
。 ProgressBar
的{{1}}属性被隐藏,可能无法在intellisense列表中显示。