gpt4 book ai didi

c# - 是否有可能 DateTime.UtcNow 在 System.Threading.Timer 过去后报告错误的时间?

转载 作者:行者123 更新时间:2023-12-04 08:43:38 25 4
gpt4 key购买 nike

我有一段代码将当前时间( DateTime.UtcNow )记录为“截止日期”,设置了一个 System.Threading.Timer ,并在计时器结束时检查是否已达到截止日期。它通过将当前时间 ( DateTime.UtcNow ) 与记录的截止日期进行比较来进行此检查。
下面是一个说明原理的简化代码示例:

class DeadlineChecker
{
private DateTime deadline;

public DeadlineChecker()
{
int waitingTimeInMilliseconds = 1200;

TimeSpan waitingTime = TimeSpan.FromMilliseconds(waitingTimeInMilliseconds);
this.deadline = DateTime.UtcNow + waitingTime;

System.Threading.Timer timer = new System.Threading.Timer(TimerElapsed);
timer.Change(waitingTimeInMilliseconds, Timeout.Infinite);
}

private void TimerElapsed(object state)
{
if (this.HasDeadlineBeenReached())
{
[...] // Do something
}

[...] // Cleanup (dispose timer etc.)
}

private bool HasDeadlineBeenReached
{
get
{
// This is only called from TimerElapsed(), so
// this should always return true, right?
return (this.deadline <= DateTime.UtcNow);
}
}
}
我现在有一个案例,其中 HasDeadlineBeenReached意外返回 false。看来我的假设是 HasDeadlineBeenReached总是在上面的示例代码中返回 true 是错误的。
有人可以解释为什么吗?在重构之前,我想了解这个问题。
即使考虑到记录在案的事实 DateTime.UtcNow有 15 毫秒的分辨率,我没想到 DateTime.UtcNow 的两个快照在时间 X 和 Y 处采取的时间跨度会小于实际耗时跨度 (Y - X)。即使两个快照都关闭了 15 毫秒,它们之间的时间跨度仍然应该等于由于计时器而过去的时间?
编辑:真正的代码试图做的是设置一个截止日期,在某些事件发生时检查该截止日期,并在达到截止日期时“做某事”。 “timer elapsed”事件只是触发截止日期检查的众多事件之一,它可以保证在没有其他事件的情况下“做某事”发生。 “做某事”是按时发生还是比截止日期晚几毫秒甚至一秒都没有关系——只需要一个 保修它发生了。
编辑 2:在接受答案后,我对代码示例进行了一些小的更改 - 我知道风格不好,但也许这会让后代更容易理解这个问题。

最佳答案

你写了:

// This should always return true, right?
不,它只会在截止日期过去时返回 true。我很感激您创建了一个 1200 毫秒的截止日期,然后告诉计时器在 1200 毫秒后触发,并期望截止日期在计时器触发的那一刻过去,但实际上计时器的计时和准确性时钟是这样的,你很可能会合理地观察到你的代码没有在你期望的精确毫秒内触发,并且时钟没有返回你期望的精确毫秒,因此当代码运行时你的截止日期仍然在 future
我建议你调整你的计时策略;将您的计时器设置为您想要“准确”间隔的一半,使用相同的逻辑检查您的截止日期是否过去,并容忍不精确(不要向用户 promise 他们可以安排他们的通知满足 1 毫秒精度)

关于c# - 是否有可能 DateTime.UtcNow 在 System.Threading.Timer 过去后报告错误的时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64440882/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com