【问题标题】:UI progressbar bug C#UI 进度条错误 C#
【发布时间】:2012-11-26 21:22:05
【问题描述】:

我有一个进度条的错误,我不知道如何处理它。

我有一个从 0 到 100 的 for 循环(或循环),只报告他的进度,然后休眠 100 毫秒:

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 0; i <= 100; i++)
    {
        backgroundWorker.ReportProgress(i);
        Thread.Sleep(100);
    }
}

在progresschanged 事件处理方法中,除了一些其他的东西之外,还有两个“if”:

if (matchProgressBar.Value == 50)
{
    OnHalfTime(); //listBox1.Add("Halftime!");
}
if (matchProgressBar.Value == 100)
{
    OnFullTime(); //listBox1.Add("Full time!");
}

两个“未知”的方法是向列表框中添加一行。在第一种情况下:“中场休息!”;在第二个中:“全职!”。在这两行之后有相同的“Thread.Sleep(5000);” //你知道,只是因为你需要在中场休息:) //

但问题是 listBox1 已经更新,但 GUI 在进度条更新前休眠了 5 秒。 (所以程序在 49% 和 99% 处停留 5 秒。)

问题:我可以做些什么来解决这个问题吗?

【问题讨论】:

  • 为什么你在进度更改处理程序中有Thread.Sleep。在 UI 线程中休眠是不好的,你需要删除它,但我不知道应该用什么替换它,因为你没有解释 Sleep 调用的目的是什么。我也觉得很奇怪,您忽略了明显重要且有问题的代码部分。

标签: c# winforms progress-bar backgroundworker


【解决方案1】:

你真的不应该在 UI 线程中调用 Sleep()。考虑重新安排一些事情,以便您暂停然后恢复您的后台线程,如果这是意图的话。

要强制更新进度条,请调用Invalidate()Update()。示例:

matchProgressBar.Invalidate();
matchProgressBar.Update();

编辑(澄清@Servy 评论):

为了清楚起见,我在上面提供了两种选择。解决问题的首选方法是删除 UI 线程中的Sleep(),而是让后台线程负责在适当的时间“暂停”。第二种选择,在 UI 线程中调用 Sleep() 之前使用 Invalidate()Update(),可能会在这个特定的实例中工作,但实际上是一个 hack,并且从维护的角度来看并不能很好地支持(即,容易与未来的代码更改中断),并且还具有其他不良属性。如果可能,请使用第一种方法。

【讨论】:

  • 我只是不太愿意 +1 一个使用 Invalidate/Update 来绕过在 UI 线程中休眠的答案,即使前半部分确实是合适的解决方案。
  • 我认为他的想法很好,但使用 Task (msdn.microsoft.com/en-us/library/…) 并使用 Task.Delay 方法来控制等待多长时间可能会更安全。我最近才被告知任务,所以我还没有在应用程序中使用它们,但据我了解,它们比控制线程安全得多。
  • 顺便说一句,调用Refresh() 相当于调用Invalidate() 然后Update()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多