我想按以下格式输出流程的剩余时间:
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 Timer,每秒运行一次:
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");
}
答案 0 :(得分:2)
根据您提供的评论,当您使用10K到10M的记录时,您可以看到波动相当大。以下是测试示例,它将向您显示波动。
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是1%,大约在1000/2/60左右完成。 32分钟后,您将完成4%。接下来你将完成6%,再过24分钟你将完成9%左右,但比如说10%。 30分钟后你应该完成14%。而现在,如果你很少更新你的textBox,那么用户会产生一种错觉,你真的知道需要多长时间,而你最终会改变一两个小时的时间,但每分钟或每一个百分比都会改变(有)你有没有在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());