将TimeSpan.TotalMilliseconds转换为长
本文关键字:转换 TotalMilliseconds TimeSpan | 更新日期: 2023-09-27 17:49:32
我有一些DateTime
变量,我想使用System.Threading.Timer
来等待,直到这个时间到来。如果时间已经过去了,我希望计时器立即滴答作响。
问题是TimeSpan.TotalMilliseconds
是double
,定时器到期时间最大类型是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);
由于(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这样的东西可能是合适的?