Welcome Guest ( Log In | Register )

Outline · [ Standard ] · Linear+

 more frequent than Sleep ?, c#

views
     
TSnarf03
post Mar 14 2024, 04:53 PM, updated 2y ago

Look at all my stars!!
*******
Senior Member
4,547 posts

Joined: Dec 2004
From: Metro Prima, Kuala Lumpur, Malaysia, Earth, Sol


in a thread,

System.Threading.Thread.Sleep(1);

sleep about ~16ms, not 1ms

and in a second i can only execute 60-62 times

i wonder if there are other alternative compare to sleep, that "sleep" lesser amount of time or allow me to have more frequent execution per second ?

if i dont add sleep, it can run many loop, but it takes up too much cpu power, about 15 to 20% of total cpu even if the thread run at minimum priority.

thanks.
jibpek
post Mar 14 2024, 04:57 PM

Enthusiast
*****
Junior Member
708 posts

Joined: Jul 2012
Depends on what you are doing, but in general use async await whenever possible, no need to run in thread, and no need to sleep.
flashang
post Mar 19 2024, 12:07 AM

Casual
***
Junior Member
355 posts

Joined: Aug 2021


If time space between 2 cycles doesn't matter,

You could do the amount of loop you want, than calculate the balance time (ms) and do a sleep(ms)

smile.gif


Mat Quasar
post Nov 28 2024, 03:05 PM

Getting Started
**
Validating
64 posts

Joined: Nov 2024
QUOTE(narf03 @ Mar 14 2024, 04:53 PM)
sleep about ~16ms,  not 1ms
*
I think because the timer resolution is not high. For example, GetTickCount is similar:

QUOTE
The resolution of the GetTickCount function is limited to the resolution of the system timer, which is typically in the range of 10 milliseconds to 16 milliseconds.


So your 16ms findings is tally with what Microsoft documented.
babisotong
post Dec 16 2024, 11:23 AM

On my way
****
Junior Member
654 posts

Joined: Feb 2013


https://chatgpt.com/

In C#, Thread.Sleep(1) does not guarantee exactly 1 millisecond of sleep. The actual sleep time might be longer due to factors such as thread scheduling, system load, or the timer resolution of the operating system. A sleep time of around 16 milliseconds (or even longer) is common in many systems, and this is why you're seeing a frequency of execution of around 60-62 times per second.

If you're looking for alternatives to Thread.Sleep(1) that allow for more frequent execution while reducing CPU usage, here are a few options you can consider:

1. Task.Delay with async/await
Task.Delay can be a better alternative in many cases. It allows for asynchronous waiting without blocking the thread, and it might be more efficient than Thread.Sleep. The delay is often more precise because it works with the task scheduler and allows other tasks to run during the wait.

Example:

csharp
Copy code
public async Task ExecuteAsync()
{
while (true)
{
// Do work here

await Task.Delay(1); // Delay asynchronously for 1 millisecond
}
}
This approach uses asynchronous programming, and the system can process other tasks while waiting, which helps to reduce CPU usage compared to a busy loop with Thread.Sleep.

2. SpinWait
If you need to wait for a very short time but still want to avoid blocking threads or wasting too much CPU, you can use SpinWait. It's a type of spin-lock that avoids consuming full CPU time while waiting, and it can be more efficient for very short wait times than Thread.Sleep in certain scenarios.

Example:

csharp
Copy code
using System.Threading;

while (true)
{
// Do work here

var sw = new SpinWait();
sw.SpinOnce(); // Spin for a short period before continuing
}
SpinWait is typically used in low-latency applications and can be much faster than using Thread.Sleep(1).

3. Timer
If you need to execute your code at regular intervals (e.g., every 16ms or so), you can use a System.Threading.Timer. A timer can help reduce CPU usage by scheduling execution at fixed intervals without continuously polling or sleeping.

Example:

csharp
Copy code
using System.Threading;

private static Timer _timer;

public static void Main()
{
_timer = new Timer(Callback, null, 0, 16); // Call every 16ms
}

private static void Callback(object state)
{
// Code to execute at regular intervals
}
This approach is efficient, as the system's thread pool handles the timer scheduling and execution.

4. Use Thread.Yield
If you're trying to allow other threads to run more frequently and you don't need precise timing, Thread.Yield() can be useful. It allows the current thread to yield control to another thread of the same or higher priority. It can reduce CPU usage in tight loops without explicitly sleeping.

Example:

csharp
Copy code
while (true)
{
// Do work here

Thread.Yield(); // Yield control to another thread
}
5. Lowering CPU Usage in Tight Loops
If you must run a tight loop but want to lower CPU usage, a combination of Thread.Sleep(1) and yielding control to the operating system could work. However, without blocking the thread for too long, you might need to balance the two. You can test different values in Thread.Sleep or use Task.Delay to control the timing more flexibly.

6. Adjusting Timer Resolution (Advanced)
On some systems, the timer resolution can be adjusted to allow for more frequent execution (e.g., lowering the system's timer tick rate from 15.6ms to something smaller). However, modifying the system timer resolution is generally not recommended, as it may have unintended consequences on system performance and power usage.

Conclusion:
If you want to balance the frequency of execution with CPU efficiency, Task.Delay combined with async/await is likely your best bet. It allows you to schedule work without wasting too much CPU, while still achieving higher execution frequency. If the goal is very short waiting times, using SpinWait or Thread.Yield may be more appropriate, depending on the context.

However, for most scenarios, using Task.Delay will be more efficient and is easier to manage.

 

Change to:
| Lo-Fi Version
0.0156sec    0.68    5 queries    GZIP Disabled
Time is now: 23rd December 2025 - 02:46 AM