【问题标题】:ProgressBar slowing my code by a factor of ~25 [Async]ProgressBar 将我的代码减慢了 ~25 [异步]
【发布时间】:2017-10-12 13:06:31
【问题描述】:

我正在做一些文件迭代,并且我的测试场景有一个最大值 = 文件中的行数(大约 130 万)的进度条。

在使用进度条之前,文件的这个迭代(逐行)大约需要 2 秒

使用进度条并为每行增加一次后,大约需要 50 秒

我的调用如下[MVP - Views - WinForms]

在演示者中:

return Task.Run(() =>
            {
                using (var reader = File.OpenText(FileName))
                {
                    while (!reader.EndOfStream)
                    {
                        var currentLine = reader.ReadLine();
                        _splitterFormView.PerformStep(1);
                        if (currentLine.ToUpper().Contains("BLA"))
                        ...
                    }
                }
            });

形式:

void PerformStep(int stepValue)
{
    Invoke(new Action(() => { progressBarStatus.Increment(stepValue); }));
}

我尝试过 BeginInvoke,但运行时没有区别。

我做错了吗?

编辑:正如我所提到的,我已经尝试过 BeginInvoke - 运行时是相同的,但它似乎更顺畅。

你们是对的 - 当我想到它时,我不知道为什么我选择 Max value 是行数并为每个调用执行 1 PerformStep() ..可能是懒惰。

【问题讨论】:

  • Invoke = 等待 UI 然后运行委托,你可能只想要BeginInvoke,也就是一劳永逸。
  • @Sinatr 问题倒数第二行:I've tried with BeginInvoke but there was no difference in runtime.
  • 您可能需要考虑报告百分比进度。将 UI 更新 130 万次可能不是一种非常有效的方法。
  • 除了下面的好答案,如果您必须使用invoke,请改用BeginInvokeInvoke 会导致线程死锁。加上Invoke 阻塞了有点失败的工作线程

标签: c# winforms performance progress-bar


【解决方案1】:

尽量避免对 UI 进行太多更新,因为这会导致表单上发生大量重绘。重绘次数会导致您的应用程序变慢。

如果您的文件有很多行,那么更新大量行的进度条将重绘进度条而不移动它。例如,如果您的进度条是 400 像素宽,但您更新了 10,000 次,那么很多重绘都是不必要的。

例如,有点像这样:

float _previousValue;

void PerformStep(int stepValue, int maximumValue)
{
    var scaledValue = (float)stepValue / (float)maximumValue * 100.0F;
    if (scaledValue != _previousValue)
    {
        BeginInvoke(new Action(() => { progressBarStatus.Increment(stepValue); }));
        _previousValue = scaledValue;
    }
}

【讨论】:

  • 这太棒了——出于另一个原因,我做了类似的事情。我将进度条的最大值分配给 characters 而不是行数,并且需要使用 long 而不是 int 所以我有一个比率变量,我保留并用来除以每次我去更新。不过我放弃了这项技术,因为它对于这么简单的任务来说似乎太傻了。
  • @mikelegg 哈哈 :) 我赞成你的几个(正确和接受的)答案作为代表凹凸。公平的公平。
【解决方案2】:

多次更新进度条没有多大意义。

将进度标准最大值缩放为较小的范围,例如0-100,然后仅在缩放数字实际发生变化时才调用更改。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-20
    • 2019-07-24
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-16
    • 2010-12-22
    相关资源
    最近更新 更多