1

我对 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 是错误的。

当我拨打电话时:

StatusToolStripProgressBar.Value = StatusToolStripProgressBar.Maximum;

我的监视窗口显示设置的值,但 GUI 尚未更新以反映这一点。如果我立即睡眠整整两秒钟,则 GUI 在睡眠前不会更新。

如果我在没有事先调用 sleep 的情况下调用 Application.DoEvents() - 它似乎什么都不做。

如果我睡着了,就调用 DoEvents——GUI 更新,然后我又睡着了。这是正确的,但我觉得我的代码令人发指。

我在这里误解了一个关键概念吗?

编辑: ProgressBarTimerStop 仅通过“RunWorkerCompleted”事件处理程序调用。

我试过这个,但没有效果:

StatusToolStripProgressBar.GetCurrentParent().Refresh();
4

2 回答 2

1

您缺少的“关键概念”是更新进度条的值不会立即告诉进度条重绘自身。

当您更新进度条时,GUI 线程会在下一个窗口重绘时重绘进度条。只有当 GUI 线程可以自由地这样做时,才会发生这种情况。通常,当窗口从操作系统接收到绘制消息时会发生这种情况。这应该由 接收Application.DoEvents,但可能是消息排队的速度不够快,无法由 接收DoEvents。您可以通过Refresh电话强制它。

于 2012-06-07T23:38:38.070 回答
0

呼吁StatusToolStripProgressBar.ProgressBar.Refresh();每一步。ProgressBar的属性ToolStripProgressBar是隐藏的,它可能不会显示在智能感知列表中。

于 2012-11-21T12:05:44.803 回答