【问题标题】:How to increase a progress bar? [closed]如何增加进度条? [关闭]
【发布时间】:2021-03-15 14:50:45
【问题描述】:

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

无论我在做什么,进度条都不会增加。

在基本概念中,我有一个 GUI 表单,它有一个免费的工作人员。在后台工作人员中,我使用自定义类从测量文件中读取数据。我想在一个文件完成后增加进度条,但不管我做什么,它什么都不做。

我已阅读文档,但没有。 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(),但这些都不起作用。

请帮忙!

提前谢谢大家!

【问题讨论】:

  • progressBar1.Value += 1; 直接引用自您链接的文章。你试过了吗?
  • 一般来说,我认识的大多数人都会建议不要在新开发中使用 Backgroundworker 来支持 Task-async / IProgress。但是如果没有看到任何代码,就很难判断该范围的重构是否合理。你真的需要添加一些代码......如果它甚至是相关的,那就太好了。
  • 您将问题标记为“asp.net”,但您可能要求的是“winforms”,或者?
  • 您是否处理了进度更改事件?自从我使用后台工作人员以来已经有很长时间了,但是从内存中,后台工作人员上有一个事件需要处理以处理进度更改。当您执行 worker.ReportProgress 时,它会触发该事件。你必须处理它,否则它什么都不做。在其中,您将根据上述评论更新进度条。 (我假设 Winforms 而不是 asp.net)。

标签: c# asp.net .net multithreading progress-bar


【解决方案1】:

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

三种解决方案:

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

示例跟随

#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.

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2020-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多