我想按以下格式输出流程的剩余时间:
d hh:mm:ss
当进程开始时,它设置一个DateTime startTime
变量为当前时间。
我的 GUI 上有计时器,每秒更新一个标签,这是我必须计算剩余时间的内容:
TimeSpan timeRemaining = TimeSpan.FromTicks(DateTime.Now.Subtract(startTime).Ticks * (iProgress.Maximum - iProgress.Value) / iProgress.Value);
并在标签上使用:
labelTimeRemaining.Text = timeRemaining.ToString(@"d\ hh\:mm\:ss");
然而,显示的时间变化在进入稳定模式时非常奇怪地跳跃了几分钟。
我知道它应该在开始时跳跃,但它应该在某个时候稳定下来,对吧?
我每秒处理大约 1~3 条记录,但每次更新剩余时间会增加 10~20 分钟。
我做错了什么或者我该如何解决这个问题?
如果您需要更多信息或代码,请告诉我。
更新
下面是我使用的部分代码:
private Stopwatch _timer = new Stopwatch();
private int _total = 0;
private int _current = 0;
启动线程或任务:
private void MyTask()
{
_timer.Reset();
_timer.Start();
for (int i = 0; i < _total; i++)
{
_current++;
Thread.Sleep(500);
}
_timer.Stop();
}
使用以下函数创建一个 winforms 计时器以每秒运行一次:
if (_timer.IsRunning && _current > 0)
{
float elapsedMin = ((float)_timer.ElapsedMilliseconds / 1000) / 60;
float minLeft = (elapsedMin / _current) * (_total - _current);
TimeSpan eta = TimeSpan.FromMinutes(minLeft);
iStatus.Text = eta.ToString(@"d\ hh\:mm\:ss");
}
最佳答案
根据您提供的评论,当您处理 10K 到 1000 万条记录时,如您所见,波动相当大。这是将显示波动的测试示例。
DateTime dt = DateTime.Now;
Thread.Sleep(3000);
TimeSpan ts = TimeSpan.FromTicks(DateTime.Now.Subtract(dt).Ticks * (100000 - 7) / 7);
Debug.WriteLine(ts.ToString());
Thread.Sleep(1000);
ts = TimeSpan.FromTicks(DateTime.Now.Subtract(dt).Ticks * (100000 - 9) / 9);
Debug.WriteLine(ts.ToString());
另外,即使你处理了整数除法
DateTime dt = DateTime.Now;
Thread.Sleep(3000);
TimeSpan ts = TimeSpan.FromTicks((long)((double)DateTime.Now.Subtract(dt).Ticks * (100000.0 - 7.0) / 7.0));
Debug.WriteLine(ts.ToString());
Thread.Sleep(1000);
ts = TimeSpan.FromTicks((long)((double)DateTime.Now.Subtract(dt).Ticks * (100000.0 - 9.0) / 9.0));
Debug.WriteLine(ts.ToString());
但是如果您可以将您的记录数标准化为百分比。假设您有 100K 条记录,1K 是百分之一,大约 1000/2/60 大约 8 分钟完成。 32 分钟后,您将完成 4%。又过了 24 分钟,你将完成 6%,你将完成大约 9%,但可以说是 10%。再过 30 分钟后,您应该完成了 14%。现在,如果你很少更新你的文本框,用户会产生你真的知道需要多长时间的错觉,你最终会改变一两个小时的时间,但每分钟或每改变一个百分比(有你曾经在 Windows 上复制过 30GB?)
DateTime dt1 = DateTime.Now;
DateTime dt2 = DateTime.Now;
dt2 = dt2.AddMinutes(32);
ts = TimeSpan.FromTicks(dt2.Subtract(dt1).Ticks * (100 - 4) / 4);
Debug.WriteLine(ts.ToString());
dt2 = dt2.AddMinutes(16);
ts = TimeSpan.FromTicks(dt2.Subtract(dt1).Ticks * (100 - 6) / 6);
Debug.WriteLine(ts.ToString());
dt2 = dt2.AddMinutes(24);
ts = TimeSpan.FromTicks(dt2.Subtract(dt1).Ticks * (100 - 10) / 10);
Debug.WriteLine(ts.ToString());
dt2 = dt2.AddMinutes(30);
ts = TimeSpan.FromTicks(dt2.Subtract(dt1).Ticks * (100 - 14) / 14);
Debug.WriteLine(ts.ToString());
关于c# - 剩余时间基于进度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13040659/