Сам по себе расчет не сложен:
long UnixTime()
{
DateTime epochStart=new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return (DateTime.UtcNow - epochStart).Ticks*100;
}
DateTime
и TimeSpan
внутренне хранят целое количество тиков, при этом один тик равен 100 нс. Я также указал начало эпохи как время UTC, потому что считаю уродливым вычитать DateTime
s с разными Kind
, даже если это работает.
Но DateTime.UtcNow
имеет очень низкую точность. Он обновляется только каждые несколько миллисекунд (типичные значения варьируются от 1 мс до 16 мс).
Чтобы получить постоянную частоту кадров, вы можете использовать StopWatch
, поскольку вам не нужно абсолютное время. Но если вы идете по этому пути, вы должны использовать напряженное ожидание. Поскольку Thread.Sleep
, таймеры ... страдают от того же ограничения.
В качестве альтернативы вы можете использовать API timeBeginPeriod(1)
, чтобы заставить Windows обновлять часы и запускать таймеры каждые 1 мс. Но это глобальная настройка и увеличивает энергопотребление. Тем не менее, это лучше, чем заняты - подождите.
Для измерения разницы во времени вы можете использовать StopWatch
с, основываясь на QueryPerformanceCounter
, но это связано с собственным набором проблем, таких как рассинхронизация между различными ядрами. Я видел, что машины QueryPerformanceCounter
перепрыгивали на несколько сотен миллисекунд, когда ваш поток был запланирован на другом ядре.