Jos*_*rke 60
为什么不?
(linesProcessed / TimeTaken)(timetaken / linesProcessed) * LinesLeft = TimeLeft
TimeLeft然后将以任何时间单位表达timeTaken.
感谢你的评论,你应该这样:
(TimeTaken / linesProcessed) * linesLeft = timeLeft
所以我们有
(10 / 100) * 200= 20秒现在10秒过去
(20 / 100) * 200= 40秒现在剩下10秒钟我们处理100多行
(30 / 200) * 100= 15秒现在我们都看到为什么复制文件对话框从3小时跳到30分钟:-)
Sco*_*pey 28
我很惊讶没有人用代码回答这个问题!
正如@JoshBerke所回答的那样,计算时间的简单方法可以编码如下:
DateTime startTime = DateTime.Now;
for (int index = 0, count = lines.Count; index < count; index++) {
// Do the processing
...
// Calculate the time remaining:
TimeSpan timeRemaining = TimeSpan.FromTicks(DateTime.Now.Subtract(startTime).Ticks * (count - (index+1)) / (index+1));
// Display the progress to the user
...
}
Run Code Online (Sandbox Code Playgroud)
这个简单的例子非常适合简单的进度计算.
但是,对于更复杂的任务,有许多方法可以改进这种计算!
例如,当您下载大文件时,下载速度可能很容易波动.要计算最准确的"ETA",一个好的算法就是只考虑过去10秒的进度.查看ETACalculator.cs以获取此算法的实现!
ETACalculator.cs来自Progression--我写的一个开源库.它为各种"进度计算"定义了一个非常易于使用的结构.它可以轻松实现报告不同类型进度的嵌套步骤.如果您担心感知性能(如@JoshBerke所建议的那样),它将对您有所帮助.
Cha*_*sch 13
不要复活一个死的问题,但我一直回来参考这个页面.
您可以在Stopwatch类上创建一个扩展方法,以获得可获得估计剩余时间跨度的功能.
static class StopWatchUtils
{
/// <summary>
/// Gets estimated time on compleation.
/// </summary>
/// <param name="sw"></param>
/// <param name="counter"></param>
/// <param name="counterGoal"></param>
/// <returns></returns>
public static TimeSpan GetEta(this Stopwatch sw, int counter, int counterGoal)
{
/* this is based off of:
* (TimeTaken / linesProcessed) * linesLeft=timeLeft
* so we have
* (10/100) * 200 = 20 Seconds now 10 seconds go past
* (20/100) * 200 = 40 Seconds left now 10 more seconds and we process 100 more lines
* (30/200) * 100 = 15 Seconds and now we all see why the copy file dialog jumps from 3 hours to 30 minutes :-)
*
* pulled from http://stackoverflow.com/questions/473355/calculate-time-remaining/473369#473369
*/
if (counter == 0) return TimeSpan.Zero;
float elapsedMin = ((float)sw.ElapsedMilliseconds / 1000) / 60;
float minLeft = (elapsedMin / counter) * (counterGoal - counter); //see comment a
TimeSpan ret = TimeSpan.FromMinutes(minLeft);
return ret;
}
}
Run Code Online (Sandbox Code Playgroud)
例:
int y = 500;
Stopwatch sw = new Stopwatch();
sw.Start();
for(int x = 0 ; x < y ; x++ )
{
//do something
Console.WriteLine("{0} time remaining",sw.GetEta(x,y).ToString());
}
Run Code Online (Sandbox Code Playgroud)
希望它会对某些人有用.
编辑:应该注意,当每个循环花费相同的时间时,这是最准确的.
编辑2:我创建了一个扩展方法,而不是子类化.
一般来说,您在处理过程中的任何时间点都知道三件事:
给定这些项目,剩余时间的估计(除非处理项目的时间是恒定的)将是
乙*丙/甲