我的时间计算给了我一个负数



以下内容工作得很好:

using System;
using System.Threading;
namespace cursor_position
{
class Program
{
static void Main(string[] args)
{
DateTime startTime = DateTime.Now;;
TimeSpan timeRemaining;
int intCount = 119;

for (int i = 0; i <= intCount; i++)
{
Thread.Sleep(2000);

Console.Clear();
timeRemaining = TimeSpan.FromTicks(DateTime.Now.Subtract(startTime).Ticks * (intCount - (i+1)) / (i+1));
Console.SetCursorPosition(0, 0);
Console.Write("ETA: ");
Console.Write(String.Format("{0} Minutes, {1} Seconds", timeRemaining.Minutes, timeRemaining.Seconds));
Console.WriteLine();
}
}
}
}

但是,就在最后,我得到了ETA计算的负数。 代码运行的时间越长(如果我增加sleepintCount),ETA减去数字就越大。

有人知道为什么吗?

当你尝试使用这样的数学计算时差时,它总是有问题的。最好通过根本不使用计数器来强化您的代码。

试试这个代码:

DateTime startTime = DateTime.Now;
DateTime targetTime = startTime.AddMinutes(1.0);
while (true)
{
DateTime now = DateTime.Now;
if (now > targetTime)
{
break;
}
else
{
TimeSpan timeRemaining = targetTime.Subtract(now);
Console.Write("ETA: ");
Console.Write(String.Format("{0} Minutes, {1} Seconds", timeRemaining.Minutes, timeRemaining.Seconds));
Console.WriteLine();
Thread.Sleep(1000);
}
}

我认为在您当前的问题中使用Thread.Sleep(1000)Thread.Sleep(2000)使我不清楚您是否要计算不确定过程的剩余时间,例如复制文件。在我看来,你只是在做一个"计时器倒计时"。

让我们编写一个通用函数来估计不确定进程的剩余时间。

public TimeSpan ComputeRemaining((int count, DateTime time) start, (int count, DateTime time) current, int end) =>
current.count - start.count == 0
? TimeSpan.MaxValue
: TimeSpan.FromSeconds((end - current.count) * current.time.Subtract(start.time).TotalSeconds / (current.count - start.count));

给定一个起始计数和DateTime,一个给定的current计数和DateTime,以及期望的end计数,这个函数产生剩余的时间。

它可以与计数上升或下降一起使用。

让我们看看它的实际效果。

var now = DateTime.Now;
var start = (count: 0, time: now.Subtract(TimeSpan.FromSeconds(5.0)));
var current = (count: 50, time: now);
var end = 100;
Console.WriteLine(ComputeRemaining(start, current, end).TotalSeconds);

所以这个例子是一个5.0秒前开始的过程,现在已经完成了 50% - 需要多长时间? 还有5.0秒。此代码正确写出5.

让我们使用示例应用进行尝试:

static void Main(string[] args)
{
var random = new Random();

DateTime startTime = DateTime.Now;
int intCount = 30;
for (int i = 0; i <= intCount; i++)
{
Thread.Sleep(random.Next(100, 2000));
TimeSpan timeRemaining = ComputeRemaining((0, startTime), (i, DateTime.Now), intCount);
Console.Write("ETA: ");
Console.Write(String.Format("{0} Minutes, {1} Seconds", timeRemaining.Minutes, timeRemaining.Seconds));
Console.WriteLine();
}
}

当我运行这个时,我得到:

预计到达时间:48 分 5 秒 预计到达时间:0 分 54 秒 预计到达时间:0 分 39 秒 预计到达时间:0 分 42 秒 预计到达时间:0 分 41 秒 预计到达时间:0 分 33 秒 预计到达时间:0 分 32 秒 预计到达时间:0 分 32 秒 预计到达时间:0 分 31 秒 预计到达时间:0 分 29 秒 预计到达时间:0 分 29 秒 预计到达时间:0 分 28 秒 预计到达时间:0 分 27 秒 预计到达时间:0 分 25 秒 预计到达时间:0 分 22 秒 预计到达时间:0 分 20 秒 预计到达时间:0 分 18 秒 预计到达时间:0 分 17 秒 预计到达时间:0 分 16 秒 预计到达时间:0 分 14 秒 预计到达时间:0 分 12 秒 预计到达时间:0 分 11 秒 预计到达时间:0 分 10 秒 预计到达时间:0 分 8 秒 预计到达时间:0 分 7 秒 预计到达时间:0 分 6 秒 预计到达时间:0 分 4 秒 预计到达时间:0 分 3 秒 预计到达时间:0 分 2 秒 预计到达时间:0 分 1 秒 预计到达时间:0 分钟,0 秒

请注意,在我的示例的早期阶段,估计值实际上会增加,因为它是根据随机输入的时间计算的。

我相信这就是你要找的。

看来你有括号问题。

假设我们已经设置了intCount = 1,那么根据您的代码,for循环将执行两次。 一次用于i=0,一次用于i=1

i = 0我们有:1234 * (intCount - (i + 1)) / (i + 1) ==> 1234*(1 - (0 + 1)) / (0 + 1)

上面的代码等于1234 * A / B,其中A是(intCount - (i + 1)),B是(i + 1)。所以首先计算1234 * A,然后将结果除以 B!

所以我们有等于 0 的1234 * (1-(0+1)),然后0 / 1等于 0。

i = 1

我们有 '1234 * (intCount - (i + 1))/(i + 1)==> 1234*(1 - (1 + 1))/(1 + 1) = -617

我们有等于 -1234 的1234 * (1-(1+1)),然后-1234 / 1等于 -1234。

要解决此问题,您需要将for循环更改为:

for (int i = 0; i < intCount; i++)

在这种情况下,循环将执行一次(i=0),您将不再获得负值。 并且还要进行此修改以解决括号问题:

timeRemaining = TimeSpan.FromTicks(DateTime.Now.Subtract(startTime).Ticks * ((intCount - (i + 1)) / (i + 1)));

最新更新