c# – 计算和显示过程“ETA / ETC”的规范,规则或指南

ETC =“预计完成时间”

我正在计算运行循环所需的时间并向用户显示一些数字,告诉他/她大约需要多长时间才能完成整个过程.我觉得这是一个普通的事情,每个人偶尔会这样做,我想知道你是否有任何指导方针.

这是我目前正在使用的一个例子:

int itemsLeft; //This holds the number of items to run through.
double timeLeft;
TimeSpan TsTimeLeft;
list<double> avrage;
double milliseconds; //This holds the time each loop takes to complete, reset every loop.

//The background worker calls this event once for each item. The total number 
//of items are in the hundreds for this particular application and every loop takes
//roughly one second.
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    //An item has been completed!

    itemsLeft--;
    avrage.Add(milliseconds);

    //Get an avgrage time per item and multiply it with items left.
    timeLeft = avrage.Sum() / avrage.Count * itemsLeft;
    TsTimeLeft = TimeSpan.FromSeconds(timeLeft);

    this.Text = String.Format("ETC: {0}:{1:D2}:{2:D2} ({3:N2}s/file)", 
        TsTimeLeft.Hours, 
        TsTimeLeft.Minutes, 
        TsTimeLeft.Seconds, 
        avrage.Sum() / avrage.Count);

    //Only using the last 20-30 logs in the calculation to prevent an unnecessarily long List<>.
    if (avrage.Count > 30) 
        avrage.RemoveRange(0, 10);

    milliseconds = 0;
}

//this.profiler.Interval = 10;
private void profiler_Tick(object sender, EventArgs e)
{
    milliseconds += 0.01;
}

由于我是职业生涯一开始的程序员,我很想知道在这种情况下你会做些什么.我主要担心的是我计算并更新每个循环的UI,这是不好的做法吗?

当涉及到这样的估计时,有什么做/不做?是否有任何首选的方式,例如每秒更新一次,每10个日志更新一次,分别计算和更新UI?此外,ETA / ETC什么时候会成为好/坏主意.

最佳答案
估算过程所花费的时间的真正问题是工作量的量化.一旦你可以量化,你可以做出更好的估计

良好估计的例子

>文件系统I / O或网络传输.无论文件系统是否具有不良性能,您都可以提前了解,可以量化要处理的总字节数,并可以测量速度.一旦你有了这些,一旦你可以监控你转移了多少字节,你就会得到一个很好的估计.随机因素可能会影响您的估计(即同时启动应用程序),但您仍然会获得有意义的值
>大流加密.由于上述原因.即使您正在计算MD5哈希值,您也总是知道已处理了多少块,要处理的块数和总数.
>项目同步.这有点棘手.如果您可以假设每单位工作量是恒定的,或者您可以在方差较低或无关紧要时对项目处理所需的时间做出较好的估计,那么您可以对流程做出另一个好的估计.选择电子邮件同步:如果您不知道邮件的字节大小(否则您会遇到案例1),但通常的做法是说大多数电子邮件的大小都相同,那么您可以使用所花时间的平均值下载/上传所有已处理的电子邮件,以估算处理单个电子邮件所需的时间.这在100%的情况下不起作用并且可能会出错,但您仍然可以看到大型帐户的进度条正在进行中

一般来说,规则是你可以很好地估计ETC / ETA(ETA实际上是预期完成操作的日期和时间),如果你有一个你知道数字的同质过程.同质性使得处理工作项目的时间与其他项目相当,即处理先前项目所花费的时间可用于估计未来.数字用于进行正确的计算.

坏估计的例子

>对大量未知文件的操作.这次您只知道要处理的文件数量(例如下载),但您事先并不知道它们的大小.一旦文件的大小变化很大,你就会发现麻烦.下载了一半的文件,当这些文件最小,总计占总字节数的10%时,可以说是半途而废?没有!你只看到进度条快速增长到50%然后慢慢增长
>异质过程.例如. Windows安装.正如@HansPassant所指出的,Windows安装提供了一个差于糟糕的估计.安装Windows软件涉及多个过程,包括:文件复制(可以估计),注册表修改(通常从未估计),执行事务代码.真正的问题是最后一个问题.下面讨论涉及执行自定义安装程序代码的事务处理
>执行通用代码.这永远无法估计.代码片段涉及条件语句.这些的执行涉及根据代码外部的条件改变路径.这意味着,例如,无论您是否安装了打印机,无论您是否拥有本地帐户或域帐户等,程序的行为都会有所不同.

结论

估计软件过程的持续时间既不是不可能的,也不是确切的*确定性*任务.

>这并非不可能,因为即使在代码片段的情况下,您也可以找到代码的模型(选择LU分解作为示例,这可能是估计的).或者您可以重新设计您的代码,将其分为估计阶段 – 首先确定分支条件 – 以及执行阶段,其中所有预定分支都被采用.我说可能因为这个任务实际上是不可能的:大多数代码将分支确定为先前条件的影响,这意味着估计分支实际上涉及运行代码.鸡肉和鸡蛋圈
>这不是一个确定性的过程.计算机系统,特别是如果多任务处理受到许多可能影响您的估计过程的随机因素的影响.在运行流程之前,您永远无法获得正确的估算.最多,您可以检测外部因素并重新估算您的流程.当你接近过程结束时(lim [x-> N] | est(N) – real(N)| == 0,你的估计和过程的实际持续时间之间的分支在数学上会收敛到零,其中N是过程持续时间)

转载注明原文:c# – 计算和显示过程“ETA / ETC”的规范,规则或指南 - 代码日志