我有一些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);
但事实证明施放long.MaxValue
加倍并返回长结果为负数(在未经检查的诅咒代码中)。请发给我代码。
编辑:显然,无论您使用哪个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);
答案 0 :(得分:3)
也许只使用Ticks属性(Ticks为Long)并乘以TimeSpan.TicksPerMillisecond(常量,每毫秒10,000个滴答)。
答案 1 :(得分:2)
由于(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);
答案 2 :(得分:2)
Timespan timespan = someUtcTime.Subtract(DateTime.UtcNow);
long time = timespan.TotalMilliseconds <= long.MaxValue ? (long)timespan.TotalMilliseconds : -1;
if (time == -1) {
sorry.nocando();
}
else {
just.doit();
}
顺便说一下:在很长一毫秒的时间里你可以有292471208的时间跨度,我认为你的代码不会被使用。太阳已经有可能已经扩展过火星,地球已经不复存在了:D
答案 3 :(得分:0)
定时器旨在等待间隔(通常短于24小时)。
您的预期用途是什么?调度程序通常会有一个事件/任务列表,并定期每分钟(可能每秒)检查一次是否需要触发任何任务。
或许像Quartz.Net这样的东西可能合适吗?