ProgressBar使我的代码减慢了~25 [Async]

时间:2017-10-12 13:06:31

标签: c# winforms performance progress-bar

我正在进行一些文件迭代,并且我的测试场景中有一个最大值=文件行数(约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值为行数且执行1次PerformStep()。可能是懒惰。

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:3)

尽量避免对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;
    }
}