将TimeSpan.TotalMilliseconds转换为长

本文关键字:转换 TotalMilliseconds TimeSpan | 更新日期: 2023-09-27 17:49:32

我有一些DateTime变量,我想使用System.Threading.Timer来等待,直到这个时间到来。如果时间已经过去了,我希望计时器立即滴答作响。

问题是TimeSpan.TotalMillisecondsdouble,定时器到期时间最大类型是long

我已经尝试使用以下代码最大限度地延长long.MaxValue的到期时间:

DateTime someUtcTime;
// Max due time to long.MaxValue
double doubleDueTime = Math.Min(
    (double)long.MaxValue,
    someUtcTime.Subtract(DateTime.UtcNow).TotalMilliseconds);
// Avoid negative numbers
long dueTime = Math.Max(0L, (long)doubleDueTime);
_timer.Change(dueTime, System.Threading.Timeout.Infinite);

但事实证明,将CCD_ 7强制加倍并返回到long会导致负数(在诅咒的未检查代码中(。请把代码发给我。


编辑:显然,无论使用哪种Timer.Change过载,它们都被限制为4294967294(UInt32.MaxValue - 1(毫秒。


解决方案:

涵盖两种极端情况(someUtcTime = DateTime.MaxValue; UtcNow = DateTime.MinValue;,反之亦然(。

const uint MAX_SUPPORTED_TIMEOUT = uint.MaxValue - 1; //0xfffffffe
DateTime someUtcTime;
double doubleDueTime = (someUtcTime - DateTime.UtcNow).TotalMilliseconds;
// Avoid negative numbers
doubleDueTime = Math.Max(0d, doubleDueTime);
// Max due time to uint.MaxValue - 1
uint dueTime = (uint)Math.Min(MAX_SUPPORTED_TIMEOUT, doubleDueTime);

将TimeSpan.TotalMilliseconds转换为长

由于(DateTime.MaxValue - DateTime.MinValue).TotalMilliseconds是315537897600000,long.MaxValue是9223372036854775807(long可以表示一个值,该值比任意两个DateTime值之间的最大可能毫秒数大4个数量级(,因此您可以在未来永远不会有太长的时间。

这就足够了:

DateTime someUtcTime;
// Max due time to long.MaxValue
double doubleDueTime = (someUtcTime - DateTime.UtcNow).TotalMilliseconds;
// Avoid negative numbers
long dueTime = Math.Max(0L, (long)doubleDueTime);
_timer.Change(dueTime, System.Threading.Timeout.Infinite);

也许只需使用Ticks属性(Ticks为Long(并乘以TimeSpan.TicksPerMillisecond(常数,每毫秒10000个Ticks(。

Timespan timespan = someUtcTime.Subtract(DateTime.UtcNow);
long time = timespan.TotalMilliseconds <= long.MaxValue ? (long)timespan.TotalMilliseconds : -1;
if (time == -1) {
 sorry.nocando();
}
else {
 just.doit();
}

BTW:用一个长毫秒,你可以有292471208年的时间跨度,我认为到那时你的代码不会被使用。太阳有可能已经膨胀过火星,而地球已经不复存在了:D

计时器设计用于等待间隔(通常短于24小时(。

你的预期用途是什么?调度器通常会有一个事件/任务列表,并每隔一分钟(可能每秒钟(定期检查是否有任何任务需要启动。

也许像Quartz.Net这样的东西可能是合适的?