如何增加进度条?

How to increase a progress bar?

这个问题似乎是一个常规问题,但事实并非如此。

无论我在做什么,进度条就是不增加。

在基本概念中,我有一个 GUI 表单,它有一个 bacgroundworker。在 backgroundworker 中,我使用自定义 class 从测量文件中读取数据。我想在完成一个文件后增加进度条,但是无论我做什么它都没有。

我已经阅读了文档,但什么也没有。 https://docs.microsoft.com/en-us/dotnet/desktop/winforms/controls/how-to-set-the-value-displayed-by-the-windows-forms-progressbar-control?view=netframeworkdesktop-4.8

我试过:

worker.ReportProgress方法

Controls.Invoke((MethodInvoker)delegate{}); 方法

Furhtermore 也尝试了 Control.Update()Control.Refress(),但这些都不起作用。

请帮忙!

提前谢谢大家!

进度条不更新的原因是 UI 无法从后台线程更新。 Backgroundworker 在后台线程上运行,使 UI 保持响应。

三种解决方案:

  1. 在 backgroundworker 中,启动一个在主 UI 线程上运行的新任务,并在那里更新进度条。这是糟糕的编码,但还有其他用例,其中 .InvokeRequired 是有效的。
  2. 使用 backgroundworker ReportProgress。在 ProgressChanged 处理程序(在 UI 线程上运行)中,正常更新进度条。
  3. 重写您的应用程序以使用“await Function1()/ async Task Fuction1() 模式而不是 Backgroundworker。这里可能会使用 .InvokeRequired。您还可以使用 EventHandlers return 响应调用者.

示例如下

#1 警告错误的编码风格!

private void bgw1_DoWork(Object sender, DoWorkEventArgs e)
{
    ...
    await Task.Run( () =>
    {
        progressBar1.InvokeIfRequired( o =>
        {
            progressBar1.Value += 1;
        } );
    });
    ...
}


public static class MyExtensions
{
    public static void InvokeIfRequired<T>(this T obj, InvokeIfRequiredDelegate<T> action) where T : ISynchronizeInvoke
    {
        if (obj.InvokeRequired)
        {
            obj.Invoke(action, new Object[] { obj });
        }
        else
        {
            action(obj);
        }
    }
}

#2 这种方式效果很好:

private void bgw1_DoWork(Object sender, DoWorkEventArgs e)
{
    ...
    worker.ReportProgress(0, 50);   //50% progress out of 100
    ...
}

private void bgw1_ProgressChanged(Object sender, ProgressChangedEventArgs e)
{
    if(e.UserState is Int32 i)
    {
        progressBar1.Value = i;
    }
}

#3

Is a complete re-write and likely outside the scope of your question.

如果对您有帮助,记得标记为答案。