/// <summary>
        /// Function to retrieve the timeGetTime time data.
        /// </summary>
        private void GetWin32Time()
        {
            if (!_initialized)
            {
                Reset();
            }

            long currentTime = WinMultimediaApi.timeGetTime();
            long ticks       = Environment.TickCount;

            // Handle wrap around every ~50 days.
            if (currentTime < _startTime)
            {
                long diff = uint.MaxValue - _startTime;
                _startTime   = diff;
                currentTime += diff;
            }

            if (ticks < _startTick)
            {
                long diff = uint.MaxValue - _startTick;
                _startTick = diff;
                ticks     += diff;
            }

            unchecked
            {
                _milliseconds = (currentTime - _startTime);
                _currentTicks = ticks - _startTick;
            }
        }
        /// <summary>
        /// Function to end the timing period for the timer.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This will end the current timing period for calls to the Win32 <a href="https://msdn.microsoft.com/en-us/library/dd757629(v=vs.85).aspx" target="_blank">timeGetTime</a> API function.
        /// </para>
        /// <para>
        /// Calls to this method must be paired with the <see cref="BeginTiming"/> static method, otherwise the system will be left in a state where the task scheduler switches tasks more often and the power
        /// saving may not trigger properly. If <see cref="BeginTiming"/> was never called, then this method will do nothing.
        /// </para>
        /// </remarks>
        /// <exception cref="Win32Exception">Thrown when the last known period value is out of range.</exception>
        public static void EndTiming()
        {
            if (_lastPeriod == null)
            {
                return;
            }

            if (WinMultimediaApi.timeEndPeriod((uint)_lastPeriod.Value) == ErrorNoCanDo)
            {
                throw new Win32Exception(Resources.GOR_ERR_TIME_CANNOT_END);
            }

            _lastPeriod = null;
        }
        /// <summary>
        /// Function to reset the timer.
        /// </summary>
        /// <exception cref="Win32Exception">Thrown when timer information cannot be retrieved from the operating system.</exception>
        public void Reset()
        {
            if (WinMultimediaApi.timeGetDevCaps(ref _timeCaps, Unsafe.SizeOf <TIMECAPS>()) != 0)
            {
                throw new Win32Exception(Resources.GOR_ERR_TIME_CANNOT_BEGIN);
            }

            if (_lastPeriod != null)
            {
                int period = _lastPeriod.Value;
                EndTiming();
                BeginTiming(period);
            }

            _startTick   = Environment.TickCount;
            _startTime   = WinMultimediaApi.timeGetTime();
            _initialized = true;
        }
        /// <summary>
        /// Function to set the timing period for the timer.
        /// </summary>
        /// <param name="period">[Optional] Minimum timer resolution, in milliseconds, for the application or device driver. A lower value specifies a higher (more accurate) resolution..</param>
        /// <remarks>
        /// <para>
        /// This will set the timing period for calls to the Win32 <a href="https://msdn.microsoft.com/en-us/library/dd757629(v=vs.85).aspx" target="_blank">timeGetTime</a> API function so that the resolution for the timer
        /// can be adjusted for maximum performance.
        /// </para>
        /// <para>
        /// Calls to this method must be paired with the <see cref="EndTiming"/> static method, otherwise the system will be left in a state where the task scheduler switches tasks more often and the power
        /// saving may not trigger properly.
        /// </para>
        /// </remarks>
        /// <exception cref="Win32Exception">Thrown when the <paramref name="period"/> value is out of range.</exception>
        public static void BeginTiming(int period = 1)
        {
            if (_lastPeriod != null)
            {
                EndTiming();
            }

            if (period < _timeCaps.MinPeriod)
            {
                period = (int)_timeCaps.MinPeriod;
            }

            if (WinMultimediaApi.timeBeginPeriod((uint)period) == ErrorNoCanDo)
            {
                throw new Win32Exception(Resources.GOR_ERR_TIME_CANNOT_BEGIN);
            }

            _lastPeriod = period;
        }