C# 提高文件处理的进度条准确性

C# Improve Progressbar Accuracy for File Processing

在我的代码中,我正在处理大量文件,并且我正在尝试在我的应用程序中实现更准确的进度显示。由于文件大小差异很大 (1-250MB),因此处理时间也不同,因此仅使用已处理文件的计数器并不能准确表示进度。

progress?.Report((i+1) * 100 / total);

相反,我查看了使用这种方法计算文件大小的因素:

progress?.Report(pb.Value + (int)(update.Size * 100 / totalSize));

但是,完成后,进度条未满,我认为这是由于除法精度下降所致。

我的 totalSize 变量可以超过 2147483647 字节,所以我不能只将进度条最大值设置为总大小并按文件大小递增该值。

有什么简单的方法可以做到这一点吗?我能想到的唯一方法是在完成最后一个元素后将进度条值设置为 100%,但我想尽可能避免这样做。谢谢

在您当前的设计中几乎没有可以改进的地方来表示更好的准确性:

My totalSize variable can exceed 2147483647 bytes, so I can't just set the progressbar max value as total size and increment the value by the file size.

  1. 使用 long 数据类型而不是 int。这样,您可以存储数据的实际大小。进度条本身不需要那么准确,但是:

    progress?.Report(pb.Value + (int)(update.Size * 100 / totalSize)); //note 100
    
  2. 您实际上可以通过将其 progress.Maximum 调得更高来提高进度条的准确性(例如,progress.Maximum = 1000 然后每个 progress.Value 算作 0.1%总计)这将使您的精度比默认进度条设置高 10 倍,前提是您的 GUI 支持这种像素精度。

  3. 最后,

But, upon completion, the progressbar isn't full which I presume is due to the loss of precision in the division.

可能是上述原因,或者...

  1. 这可能是由于图形表示。由于更新进度条图形需要一点延迟。您可能已经完成了流程并为进度条赋予了正确的值(如果您使用我的答案,则为 100/100 或 1000/1000),但 UI 尚未更新。如果你想延迟一点,只需使用Thread.Sleep

  2. 此外,另一个可能的原因是四舍五入在某处搞砸了,因此它给你的四舍五入值有点像 99/100。为防止这种情况,我建议在 progress.Value = N; 赋值的最终表示发生之前使用 double 而不是整数类型来处理数据。如果 double 精度仍然给您带来非常小的错误,您也可以考虑使用 Math.Round。这里重要的是良好的调试以隔离原因,然后我们可以应用适当的修复。

  3. 或者也可能是由于上述综合原因,您必须同时应用这两个修复程序。