У меня есть некоторая переменная 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);