Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8946341
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 15, 20262026-06-15T12:29:09+00:00 2026-06-15T12:29:09+00:00

For the following code: The actual interval is always 1014.01 ms rather than 1000

  • 0

For the following code:

The actual interval is always 1014.01 ms rather than 1000 ms …

I’ve also tried to use System.Windows.Forms.Timer, System.Threading.Timer and the WinAPI Sleep(int) function in C++, but the additional increase of 14.01 ms always exists.

The System Clock of Windows 8 is exact, but both the .NET timers and the Sleep(int) function of Windows API are inexact.

public partial class Form1 : Form
{
    private long ticks;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        System.Timers.Timer timer = new System.Timers.Timer(1000);
        // The actual interval is always 1014.01 ms ...
        // I've also tried to use System.Windows.Forms.Timer, System.Threading.Timer
        // and the WinAPI Sleep(int) function in C++, but the additional increase
        // of 14.01 ms always exists.
        timer.Elapsed += timer_Elapsed;
        timer.Start();
        ticks = System.DateTime.Now.Ticks;
    }

    void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        textBox1.Text = Math.Round((e.SignalTime.Ticks - ticks) / 10000.0, 2).ToString();
        ticks = e.SignalTime.Ticks;
    }
}

Update:

  • The native Sleep function (ReactOS):
// Call SleepEx with bAlertable = FALSE
VOID WINAPI Kernel32.Sleep(IN DWORD dwMilliseconds)

// Call NtDelayExecution with Alertable = bAlertable
// and DelayInterval.QuadPart = dwMilliseconds * -10,000
DWORD WINAPI Kernel32.SleepEx(IN DWORD dwMilliseconds, IN BOOL bAlertable)

// The syscall stub - call the kernel mode function NtDelayExecution directly
NTSTATUS NTAPI Ntdll.NtDelayExecution(IN BOOLEAN Alertable, IN PLARGE_INTEGER DelayInterval)

// Check for the access permissions of DelayInterval and then call KeDelayExecutionThread
NTSYSCALLAPI NTSTATUS NTAPI Ntoskrnl.NtDelayExecution(IN BOOLEAN Alertable, IN PLARGE_INTEGER DelayInterval)

// Core implement of the sleep/delay function
NTKERNELAPI NTSTATUS NTAPI Ntoskrnl.KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable,
IN PLARGE_INTEGER Interval OPTIONAL)
{
    PKTIMER Timer;
    PKWAIT_BLOCK TimerBlock;
    PKTHREAD Thread = KeGetCurrentThread();
    NTSTATUS WaitStatus;
    BOOLEAN Swappable;
    PLARGE_INTEGER OriginalDueTime;
    LARGE_INTEGER DueTime, NewDueTime, InterruptTime;
    ULONG Hand = 0;

    /* If this is a user-mode wait of 0 seconds, yield execution */
    if (!(Interval->QuadPart) && (WaitMode != KernelMode))
    {
        /* Make sure the wait isn't alertable or interrupting an APC */
        if (!(Alertable) && !(Thread->ApcState.UserApcPending))
        {
            /* Yield execution */
            NtYieldExecution();
        }
    }

    /* Setup the original time and timer/wait blocks */
    OriginalDueTime = Interval;
    Timer = &Thread->Timer;
    TimerBlock = &Thread->WaitBlock[TIMER_WAIT_BLOCK];

    /* Check if the lock is already held */
    if (!Thread->WaitNext) goto WaitStart;

    /*  Otherwise, we already have the lock, so initialize the wait */
    Thread->WaitNext = FALSE;
    KxDelayThreadWait();

    /* Start wait loop */
    for (;;)
    {
        /* Disable pre-emption */
        Thread->Preempted = FALSE;

        /* Check if a kernel APC is pending and we're below APC_LEVEL */
        if ((Thread->ApcState.KernelApcPending) && !(Thread->SpecialApcDisable) &&
            (Thread->WaitIrql < APC_LEVEL))
        {
            /* Unlock the dispatcher */
            KiReleaseDispatcherLock(Thread->WaitIrql);
        }
        else
        {
            /* Check if we have to bail out due to an alerted state */
            WaitStatus = KiCheckAlertability(Thread, Alertable, WaitMode);
            if (WaitStatus != STATUS_WAIT_0) break;

            /* Check if the timer expired */
            InterruptTime.QuadPart = KeQueryInterruptTime();
            if ((ULONGLONG)InterruptTime.QuadPart >= Timer->DueTime.QuadPart)
            {
                /* It did, so we don't need to wait */
                goto NoWait;
            }

            /* It didn't, so activate it */
            Timer->Header.Inserted = TRUE;

            /* Handle Kernel Queues */
            if (Thread->Queue) KiActivateWaiterQueue(Thread->Queue);

            /* Setup the wait information */
            Thread->State = Waiting;

            /* Add the thread to the wait list */
            KiAddThreadToWaitList(Thread, Swappable);

            /* Insert the timer and swap the thread */
            ASSERT(Thread->WaitIrql <= DISPATCH_LEVEL);
            KiSetThreadSwapBusy(Thread);
            KxInsertTimer(Timer, Hand);
            WaitStatus = (NTSTATUS)KiSwapThread(Thread, KeGetCurrentPrcb());

            /* Check if were swapped ok */
            if (WaitStatus != STATUS_KERNEL_APC)
            {
                /* This is a good thing */
                if (WaitStatus == STATUS_TIMEOUT) WaitStatus = STATUS_SUCCESS;

                /* Return Status */
                return WaitStatus;
            }

            /* Recalculate due times */
            Interval = KiRecalculateDueTime(OriginalDueTime,
                                            &DueTime,
                                            &NewDueTime);
        }

WaitStart:
        /* Setup a new wait */
        Thread->WaitIrql = KeRaiseIrqlToSynchLevel();
        KxDelayThreadWait();
        KiAcquireDispatcherLockAtDpcLevel();
    }

    /* We're done! */
    KiReleaseDispatcherLock(Thread->WaitIrql);
    return WaitStatus;

NoWait:
    /* There was nothing to wait for. Did we have a wait interval? */
    if (!Interval->QuadPart)
    {
        /* Unlock the dispatcher and do a yield */
        KiReleaseDispatcherLock(Thread->WaitIrql);
        return NtYieldExecution();
    }

    /* Unlock the dispatcher and adjust the quantum for a no-wait */
    KiReleaseDispatcherLockFromDpcLevel();
    KiAdjustQuantumThread(Thread);
    return STATUS_SUCCESS;
}

// Note that the Windows API Sleep(0) will also call NtYieldExecution(), refer to
// the function Ntoskrnl.KeDelayExecutionThread above
  • The timeouts of the .NET Sleep(1), Sleep(0), Yield() and empty statement:
for (; ; )
{
    Stopwatch sw = Stopwatch.StartNew();
    // Thread.Sleep(1); // between 36000 and 39000
    // Thread.Sleep(0); // 2 or 3
    Thread.Yield(); // 1 or 2
    // empty statement // always 0
    Console.WriteLine(sw.ElapsedTicks);
    sw.Restart();
}
  • The Stopwatch depends on the WinAPI functions QueryPerformanceCounter and QueryPerformanceFrequency:
static Stopwatch() {
    bool succeeded = SafeNativeMethods.QueryPerformanceFrequency(out Frequency); 
    if(!succeeded) {
        IsHighResolution = false;
        Frequency = TicksPerSecond;
        tickFrequency = 1; 
    }
    else {
        IsHighResolution = true; 
        tickFrequency = TicksPerSecond;
        tickFrequency /= Frequency; 
    }
}

public static long GetTimestamp() {
    if(IsHighResolution) {
        long timestamp = 0;
        SafeNativeMethods.QueryPerformanceCounter(out timestamp);
        return timestamp;
    }
    else {
        return DateTime.UtcNow.Ticks; 
    }
}
  • The Stopwatch is exact, but neither DateTime.UtcNow.Ticks nor Environment.TickCount is exact:
// Stopwatch is extremely exact without Thread.Sleep, always 1000.00 ms
// But the combination of Stopwatch + Thread.Sleep(1000) is inexact
// Stopwatch is very exact with Thread.Sleep + a spin check, always 1000 ms
thread = new Thread(() =>
{
    var setText = new Action<long>(t => textBox1.Text
        = Math.Round(t * 1000.0 / Stopwatch.Frequency, 2).ToString());
    var sw = Stopwatch.StartNew();
    for (; ; )
    {
        // In most cases 986 is exact enough, but very rarely it might produce
        // a "1001", so use 985 here
        Thread.Sleep(985);
        while (sw.ElapsedTicks < Stopwatch.Frequency)
            // Use Sleep(0) instead of Yield() or empty statement
            Thread.Sleep(0);
        // The actual interval is always 1000 ms instead of 1014.01 ms
        // The Invoke method must be used since InvokeRequired is true
        Invoke(setText, sw.ElapsedTicks);
        sw.Restart();
    }
});
thread.Start();

// DateTime.UtcNow.Ticks and DateTime.Now.Ticks are both inexact with
// Thread.Sleep + a spin check, still 1014.01 ms
thread = new Thread(() =>
{
    var setText = new Action<long>(t => textBox1.Text
    = Math.Round((t - ticks) / 10000.0, 2).ToString());
    for (; ; )
    {
        Thread.Sleep(985);
        while (DateTime.UtcNow.Ticks < ticks + 10000000)
            Thread.Sleep(0);
        var t = DateTime.UtcNow.Ticks;
        Invoke(setText, t);
        ticks = t;
    }
});
thread.Start();

// Environment.TickCount is inexact with Thread.Sleep + a spin check,
// still 1014 ms (int value)
thread = new Thread(() =>
{
    var setText = new Action<int>(t => textBox1.Text
    = (t - msecs).ToString());
    for (; ; )
    {
        Thread.Sleep(985);
        while (Environment.TickCount < msecs + 1000)
            Thread.Sleep(0);
        var t = Environment.TickCount;
        Invoke(setText, t);
        msecs = t;
    }
});
thread.Start();

private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
    thread.Abort();
}

References:

Source code of the ReactOS

Official Reference Source of the .NET 4.5 Update 1

The Shared Source CLI 2.0 (for native functions)

SwitchToThread/Thread.Yield vs. Thread.Sleep(0) vs. Thead.Sleep(1)

Thanks to everyone for help!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-15T12:29:10+00:00Added an answer on June 15, 2026 at 12:29 pm

    Sleep causes the OS to not schedule the thread until the time is up. Note that schedule != run.

    Scheduling only adds the thread to a queue so it’ll get run eventually, but not always immediately. For instance, if there’s already a thread running, you still need to wait for its time slice to finish. If there are higher-priority threads in the queue, those could also run before it.

    You should never count on Sleep() lasting exactly the amount of time you give it — only at least that amount of time.

    Timers basically operate the same way, but don’t block a thread while they’re waiting to be scheduled.

    Also, you should be using Environment.TickCount or Stopwatch to measure elapsed time, not DateTime, which is affected by changes to the system time.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have the following code: The actual problem is the non-quoted code. I want
Following code takes like 2500 milliseconds on an i7-*3.4 GHz windows-7 64-bit computer to
I use the following code to log a map, it is fast when it
The following code is for authenticating to a windows AD server using Java+Kerberos and
I have the following code that I'm trying to use to populate a ComboBox,
I'm following the yesod book example about how to use monadic forms. My getRootR
Following code produces a nested array as a result for keys containing three items:
Following code worked fine abstract class FunctionRunnable<V> implements Runnable { protected abstract V calculate();
Following code: <%= render 'shared/error_messages', f.object %> where f.object is instance of a class
Following code gets executed whenever I want to persist any entity. Things seems to

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.