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.
使用 long
数据类型而不是 int
。这样,您可以存储数据的实际大小。进度条本身不需要那么准确,但是:
progress?.Report(pb.Value + (int)(update.Size * 100 / totalSize)); //note 100
您实际上可以通过将其 progress.Maximum
调得更高来提高进度条的准确性(例如,progress.Maximum = 1000
然后每个 progress.Value
算作 0.1%总计)这将使您的精度比默认进度条设置高 10 倍,前提是您的 GUI 支持这种像素精度。
最后,
But, upon completion, the progressbar isn't full which I presume is
due to the loss of precision in the division.
可能是上述原因,或者...
这可能是由于图形表示。由于更新进度条图形需要一点延迟。您可能已经完成了流程并为进度条赋予了正确的值(如果您使用我的答案,则为 100/100 或 1000/1000),但 UI 尚未更新。如果你想延迟一点,只需使用Thread.Sleep
。
此外,另一个可能的原因是四舍五入在某处搞砸了,因此它给你的四舍五入值有点像 99/100
。为防止这种情况,我建议在 progress.Value = N;
赋值的最终表示发生之前使用 double
而不是整数类型来处理数据。如果 double
精度仍然给您带来非常小的错误,您也可以考虑使用 Math.Round
。这里重要的是良好的调试以隔离原因,然后我们可以应用适当的修复。
或者也可能是由于上述综合原因,您必须同时应用这两个修复程序。
在我的代码中,我正在处理大量文件,并且我正在尝试在我的应用程序中实现更准确的进度显示。由于文件大小差异很大 (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.
使用
long
数据类型而不是int
。这样,您可以存储数据的实际大小。进度条本身不需要那么准确,但是:progress?.Report(pb.Value + (int)(update.Size * 100 / totalSize)); //note 100
您实际上可以通过将其
progress.Maximum
调得更高来提高进度条的准确性(例如,progress.Maximum = 1000
然后每个progress.Value
算作 0.1%总计)这将使您的精度比默认进度条设置高 10 倍,前提是您的 GUI 支持这种像素精度。最后,
But, upon completion, the progressbar isn't full which I presume is due to the loss of precision in the division.
可能是上述原因,或者...
这可能是由于图形表示。由于更新进度条图形需要一点延迟。您可能已经完成了流程并为进度条赋予了正确的值(如果您使用我的答案,则为 100/100 或 1000/1000),但 UI 尚未更新。如果你想延迟一点,只需使用
Thread.Sleep
。此外,另一个可能的原因是四舍五入在某处搞砸了,因此它给你的四舍五入值有点像
99/100
。为防止这种情况,我建议在progress.Value = N;
赋值的最终表示发生之前使用double
而不是整数类型来处理数据。如果double
精度仍然给您带来非常小的错误,您也可以考虑使用Math.Round
。这里重要的是良好的调试以隔离原因,然后我们可以应用适当的修复。或者也可能是由于上述综合原因,您必须同时应用这两个修复程序。