Both Thread.Sleep(timeout) and resetEvent.Wait(timeout) cause execution to pause for at least timeout milliseconds, so is there a difference between them? I know that Thread.Sleep causes the thread to give up the remainder of its time slice, thus possibly resulting in a sleep that lasts far longer than asked for. Does the Wait(timeout) method of a ManualResetEvent object have the same problem?
Edit: I'm aware that a ManualResetEvent's main point is to be signaled from another thread - right now I'm only concerned with the case of an event's Wait method with a timeout specified, and no other callers setting the event. I want to know whether it's more reliable to awaken on-time than Thread.Sleep
Thread.Sleep(timeout) causes an unconditional wait before execution is resumed. resetEvent.WaitOne(timeout) causes the thread to wait until either (1) the event is triggered, or (2) the timeout is reached.
The point of using events is to trigger them from another thread, so you can directly control when the thread wakes up. If you don't need this, you shouldn't be using event objects.
EDIT: Timing-wise, they are both equally reliable. However, your comment about "awakening on time" worries me. Why do you need your code to wake up on time? Sleep and WaitOne aren't really designed with precision in mind.
Only if timeout is below 50ms or so and you need the reliability, you should look into alternate methods of timing. This article looks like a pretty good overview.
The main difference between Thread.Sleep and ManualResetEvent.WaitOne is that you can signal to a thread waiting on a ManualResetEvent using the Set method, causing the thread to wake up earlier than the timeout.
If you don't signal then I would expect them to behave in a very similar way.
From .NET Reflector I can see that the method ManualResetEvent.WaitOne eventually results in a call to an extern method with the following signature:
int WaitOneNative(SafeWaitHandle waitHandle,
uint millisecondsTimeout,
bool hasThreadAffinity,
bool exitContext);
Whereas Thread.Sleep calls this extern method:
void SleepInternal(int millisecondsTimeout);
Unfortunately I don't have the source code for these methods, so I can only guess. I'd imagine that in both calls result in the thread getting scheduled out while it is waiting for the time out to expire, with neither being particularly more accurate than the other.
For delays and periodics I have found Monitor.Wait a good choice..
object timelock = new object();
lock (timelock) { Monitor.Wait(timelock, TimeSpan.FromMilliseconds(X.XX)); }
This gives a excellent result....~1ms jitter or better depending on application specifics.
As you may already know Thread.Sleep(X) is unreliable and cannot be canceled....I avoid it like the plague.
The Sleep() function hasn't worked this way for a long time. Its accuracy is determined by the multimedia timer period, something you can change by P/Invoking timeBeginPeriod(). Unfortunately, on my machine I've got some kind of program that sets this period to one millisecond, making sleeps accurate down to a millisecond. Here's some code to try for yourself:
using System;
using System.Diagnostics;
using System.Threading;
using System.Runtime.InteropServices;
class Program {
static void Main(string[] args) {
//timeBeginPeriod(1);
var sw1 = Stopwatch.StartNew();
for (int ix = 0; ix < 100; ++ix) Thread.Sleep(10);
sw1.Stop();
var sw2 = Stopwatch.StartNew();
var mre = new ManualResetEvent(false);
for (int ix = 0; ix < 100; ++ix) mre.WaitOne(10);
sw1.Stop();
Console.WriteLine("Sleep: {0}, Wait: {1}", sw1.ElapsedMilliseconds, sw2.ElapsedMilliseconds);
Console.ReadLine();
//timeEndPeriod(1);
}
[DllImport("winmm.dll")]
private static extern int timeBeginPeriod(int period);
[DllImport("winmm.dll")]
private static extern int timeEndPeriod(int period);
}
Output on my machine:
Sleep: 999, Wait: 1003
with a variability of about 5 milliseconds.
As others have mentioned, the difference is WaitOne could return before the sleep time if signaled. Sleep is guaranteed to wait for the sleep time.
Thread.Sleep in reflector calls:
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void SleepInternal(int millisecondsTimeout);
ManualResetEvent.Wait in reflector calls:
private static extern int WaitOneNative(SafeWaitHandle waitHandle, uint millisecondsTimeout, bool hasThreadAffinity, bool exitContext);
Not sure if there is a difference between the two, but I'll see if I can find something.
The Sleep continues for the specified time. The event wait can end sooner if the event is signalled. This is the purpose of events: to allow one thread to tell another to wake up.
In one thread you'd say:
mre.WaitOne(10000); // ten seconds
Console.WriteLine("Woke up!");
In another you'd say:
mre.Set(); // this causes `WaitOne` to return in the first thread
Without the call to Set in the other thread, the first thread would effectively sleep for 10 seconds.
Related
I notice the timer is not correct.
This is a very simple C# code: it will print current date/time every 1 minute.
My expected result is: let it run at 3:30 PM then we will have: 3:31 PM, 3:32 PM, 3:33 PM, ...
But sometime don't receive above result: sometime it is 3:31 PM, 3:32 PM, 3:34 PM, ...
So it lost 1 row.
Could anyone point me what is problem?
class Program
{
static Timer m_Timer;
static int countDown;
static void Main(string[] args)
{
countDown = 60;
m_Timer = new Timer(TimerCallback, null, 0, 1000);
while (true) { System.Threading.Thread.Sleep(10); };
}
static void TimerCallback(Object o)
{
countDown -= 1;
if (countDown <= 0)
{
Console.WriteLine(" ===>>>>>" + System.DateTime.Now.ToString());
countDown = 60;
}
System.Threading.Thread.Sleep(10000); //long running code demo
}
}
System.Threading.Timer runs on threads from thread pool. You run callback function which runs on one thread in pool every 1s and block it for 10s using sleep. Depending on how many threads you have in thread pool at some timepoints they all may be blocked and wait or .NET should allocate new thread up to the maximum of threads in pool for you.
From comments extended answer.
Each function is independent and it does not wait until another processing finish. A simple task is: call a function to do something every 1 minutes. "do something" in my case is saving local variables into SQL server. This process is fast not slow. I use 1 timer for many functions because each function is schedule in different cycle. For example, function 1 is triggered every 1 minute, function 2 is triggered every 10 seconds ... That why I use the timer 1 second.
Your use case seems to be more complex as I read it from initial question. You have different tasks and try to implement sort of scheduler. Maybe each particular tasks is fast but all together some runs may be longer and blocking. Not sure how this logic was well implemented but there could be a lot of edge cases e.g. some run was missed etc.
How I would approach it?
I would not try to implement on my own if scheduler can be more complex. I would pick ready solution, e.g. Quartz.NET. They consider edge cases and help to scale on cluster with needed and help with config.
In any case I would refactor bigger schedule to have each task to run on its schedule based on configuration (custom implementation or Quartz) as smaller tasks
I would scale your "queue" of tasks first locally by introducing some queue, for example using ConcurrentQueue or BlockingCollection or any produce-consumer to limit number of threads and if performance of such execution is not good scale on cluster. By doing so you can at least guarantee that N tasks can be scheduled and executed locally and everything beyond is queued. Maybe having some priorities for tasks can also help because there might be execution which could be missed but there are execution which must run on schedule.
I doubt it is a good idea to start from thread timer execution other threads or tasks if most likely you already have problems with threading.
You problem is not with System.Threading.Timer, it does its job well. Your use case is more complex.
Windows - is not real time operating system. So, if you expect that timer waits ecactly 1 second - it's wrong. There are many reasonsm when timer can wait more time. Because of timer resolution or other high load operations.
If you like newer .NET TPL syntax yo can write it like this:
using System;
using System.Threading.Tasks;
namespace ConsoleApp1
{
internal class Program
{
private static void Main(string[] args)
{
Repeat(TimeSpan.FromSeconds(10));
Console.ReadKey();
}
private static void Repeat(TimeSpan period)
{
Task.Delay(period)
.ContinueWith(
t =>
{
//Do your staff here
Console.WriteLine($"Time:{DateTime.Now}");
Repeat(period);
});
}
}
}
The above code causes, that every second you run 10-second "demo" (sleep). You will run 10 worker threads simultanously.
Are you sure, this is what you are trying to achieve?
To see what really happens in your app, simply add:
Console.WriteLine($"Time:{DateTime.Now.ToString("hh:mm:ss.fff tt")},Thread:{Thread.CurrentThread.ManagedThreadId},countDown:{countDown}");
in the beginning of TimerCallback. You will notice, that timespan between following callbacks are not exactly 1000ms (usually it is a little bit more). This is perfectly normal in non-rtc OS, and, in most cases - it's not a problem. Just keep in mind, that Timer is not exact.
Moreover, if you are trying to use Timer that way, and trying to count ticks - these little errors cumulates in following ticks.
I just post what found here for people that have problem like me.
I found the answer from another thread.
I use "HighResolutionTimer.cs" and it works perfect:
https://gist.github.com/DraTeots/436019368d32007284f8a12f1ba0f545
I have a console server in C# that keeps running in a while(true) loop. But that takes > 50% CPU even if it is doing nothing. I tried Thread.Sleep it worked! Not eating my CPU anymore but, it do not resumes in the exact time specified and is not considered good practice. Am I doing the right thing? Or is there any other way than using while(true) and Thread.Sleep?
When you want to suspend thread for a while without consuming CPU resources, you usually use some WaitHandle (such as AutoResetEvent or ManualResetEvent) and call it's WaitOne() method to suspend thread until event that is supposed to wake it up occurs (e.g. key is pressed, new network connection arrives, asynchronous operation finishes, etc.).
To wake up thread periodically, you can use timer. I'm not aware of any timer in .NET Framework, that provides WaitHandle (of course you can easily create such class yourself), so have to use Timer and call AutoResetEvent.Set() manually on each tick in it's callback.
private static AutoResetEvent TimerWaitHandle = new AutoResetEvent(false);
static void Main()
{
// Initialize timer
var timerPeriod = TimeSpan.FromMilliseconds(500);
Timer timer = new Timer(TimerCallback, null, timerPeriod, timerPeriod);
while(true)
{
// Here perform your game logic
// Suspend main thread until next timer's tick
TimerWaitHandle.WaitOne();
// It is sometimes useful to wake up thread by more than event,
// for example when new user connects etc. WaitHandle.WaitAny()
// allows you to wake up thread by any event, whichever occurs first.
//WaitHandle.WaitAny(new[] { TimerWaitHandle, tcpListener.BeginAcceptSocket(...).AsyncWaitHandle });
}
}
static void TimerCallback(Object state)
{
// If possible, you can perform desired game logic here, but if you
// need to handle it on main thread, wake it using TimerWaitHandle.Set()
TimerWaitHandle.Set();
}
I can't comment, so i'll put it here.
Theorically with Thread.sleep(1) it won't use that much CPU.
You can get more info from this question/answer: What is the impact of Thread.Sleep(1) in C#?
You can use System.Threading.Timer class. It Provides a mechanism for executing a method on a thread pool thread at specified intervals.
Example
public void Start()
{
}
int dueTime = 1000;
int periodTS = 5000;
System.Threading.Timer myTimer = new System.Threading.Timer(new TimerCallback(Start), null, dueTime, periodTS);
This will call start method after 1 second from calling it and after that start will be called after every 5 second.
You can read more about Timer class here.
In a windows form application what is the impact of calling Thread.Sleep(1) as illustrated in the following code:
public Constructor()
{
Thread thread = new Thread(Task);
thread.IsBackground = true;
thread.Start();
}
private void Task()
{
while (true)
{
// do something
Thread.Sleep(1);
}
}
Will this thread hog all of the available CPU?
What profiling techniques can I use to measure this Thread's CPU usage ( other than task manager )?
As stated, your loop will not hog the CPU.
But beware: Windows is not a real-time OS, so you will not get 1000 wakes per second from Thread.Sleep(1). If you haven't used timeBeginPeriod to set your minimum resolution you'll wake about every 15 ms. Even after you've set the minimum resolution to 1 ms, you'll still only wake up every 3-4 ms.
In order to get millisecond level timer granularity you have to use the Win32 multimedia timer (C# wrapper).
No it won't hog the CPU, it will just pause your thread for at least that long. While your thread is paused, the operating system can schedule another, unrelated thread to make use of the processor.
Thread.Sleep(1) as stated will not hog the CPU.
Here is what happens when a thread sleeps (more or less):
Thread.Sleep is translated into a system call, which in turn triggers a trap (an interruption that allows the operating system to take control)
The operating system detects the call to sleep and marks your thread as blocked.
Internally the OS keeps a list of threads that need to be waken up and when it should happen.
Since the thread is no longer using the CPU the OS...
If the parent process has not used up all of its time slice the OS will schedule another thread of the process for execution.
Otherwise another process (or the idle process) will start executing.
When the time is due, your thread will be scheduled again for execution, that doesn't mean it will start executing automatically.
On a final note, I don't exactly know what you are doing but it would seem you're trying to take the role of the scheduler, that is, sleeping to provide the CPU with time to do other things...
In a few cases (very few indeed) it might be all right, but mostly you should let the scheduler do its work, it probably knows more than you do, and can make the work better than you can do it.
Small sleep times should be avoided as a thread giving up its time slice gets a priority boost when resignaled, and that can lead to high context switches. In a multithreaded / server application, this can lead to a thrashing effect as the threads are battling for CPU time. Instead, rely on asynchronous functions and synchronization objects such as critical sections or mutexes / semaphores.
As Bob Nadler mentioned Thread.Sleep(1) does not guarantee a sleep time of 1ms.
Here is an example using the Win32 multimedia timer to force a sleep of 1ms.
[DllImport("winmm.dll")]
internal static extern uint timeBeginPeriod(uint period);
[DllImport("winmm.dll")]
internal static extern uint timeEndPeriod(uint period);
timeBeginPeriod(1);
while(true)
{
Thread.Sleep(1); // will sleep 1ms every time
}
timeEndPeriod(1);
Testing this in a C# GUI application, I found that the application used about 50% of my CPU.
For more discussion on this topic see the following forum thread:
http://www.dotnet247.com/247reference/msgs/57/289291.aspx
This is an old thread that comes up in a lot of my searches, but Win7 has a new scheduler and seems to behave differently than the above.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
DateTime dtEnd = DateTime.Now.AddSeconds(1.0);
int i = 0;
while (DateTime.Now < dtEnd)
{
i++;
Thread.Sleep(1);
}
Console.WriteLine(i.ToString());
i = 0;
long lStart = DateTime.Now.Ticks;
while (i++ < 1000)
Thread.Sleep(1);
long lTmp = (DateTime.Now.Ticks - lStart) / 10000;
Console.WriteLine(lTmp.ToString());
Console.Read();
}
}
}
With the above code, My first result gave 946. So in the timespan of 1 second using 1ms sleeps, I got 946 wake ups. That's very close to 1ms.
The second part asks how long it takes to do 1000 sleep events at 1ms each. I got 1034ms. Again, nearly 1ms.
This was on a 1.8ghz core2duo + Win7 using .Net 4.0
Edit: remember, sleep(x) doesn't mean wake up up at this time, it means wake me up no earlier than this time. It is not guaranteed. Although, you can increase the priority of the thread and Windows should schedule your thread before lower priority threads.
No, it won't hog all available CPU, because a sleeping thread will be switched out by the OS' scheduler when another thread has work to do.
No, it will not. You'll barely see it. Somewhere less than 1000 times a second this thread will wake up and do next to nothing before sleeping again.
Edit:
I had to check. Running on Java 1.5 , this test
#Test
public void testSpeed() throws InterruptedException {
long currentTime = System.currentTimeMillis();
int i = 0;
while (i < 1000)
{
Thread.sleep(1);
i++;
}
System.out.println("Executed in " + (System.currentTimeMillis() - currentTime));
}
Ran at approximately 500 sleeps per second on my 3ghz machine. I suppose C# should be fairly much the same. I assume someone will report back with C# numbers for this intensely important real-world benchmark. There was no observable CPU usage, by the way.
A thread can at most hog one (logical) CPU at a time. And a 1ms sleep will not be hogging. Don't sweat it.
also have a look at this: msdn forum
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
namespace Test
{
public static class Program
{
public static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
for (int i = 0; i < 10; ++i)
{
sw.Reset();
sw.Start();
Thread.Sleep(50);
sw.Stop();
Console.WriteLine("(default) Slept for " + sw.ElapsedMilliseconds);
TimeBeginPeriod(1);
sw.Reset();
sw.Start();
Thread.Sleep(50);
sw.Stop();
TimeEndPeriod(1);
Console.WriteLine("(highres) Slept for " + sw.ElapsedMilliseconds + "\n");
}
}
[DllImport("winmm.dll", EntryPoint="timeBeginPeriod", SetLastError=true)]
private static extern uint TimeBeginPeriod(uint uMilliseconds);
[DllImport("winmm.dll", EntryPoint="timeEndPeriod", SetLastError=true)]
private static extern uint TimeEndPeriod(uint uMilliseconds);
}
}
I’ve been scratching my head for days about this problem. I’m trying to get a timer that restarts the application every 50s. The code basically fetches database items every 50s and does something. However it seems to hang overnight when there has been a long period of inactivity. I've just shown a skeleton of the code below. In the code also theres’s a connection to a mysql db, rest hhtpwebrequest, and a ssh using renci.ssh to get to another computer. All these are closed properly.
static void Main(string[] args)
{
Timer timer = new Timer(state => workDone(), null, 50000, 50000);
workDone();
}
private static void workDone()
{
//Hold program open for next cycle
Console.ReadLine();
}
Somewhere towards the end of my code i also used Console.ReadLine(); to hold the program open. Is there a reason why this should hang after a period of inactivity? I have a suspicion it’s my code but it may also be the linux box? Will post the whole code if need be. Thank you so much for all your help. Cheers.
I guess you are trying to do this:
private static Timer timer;
static void Main(string[] args)
{
timer = new Timer(state => workDone(), null, 0, 50000);
// Hold program open...
Console.ReadLine();
}
private static void workDone()
{
// Do work
}
I think that by blocking in the callback you'll eventually use up the threadpool.
From MSDN:
The method specified for callback should be reentrant, because it is called on ThreadPool threads. The method can be executed simultaneously on two thread pool threads if the timer interval is less than the time required to execute the method, or if all thread pool threads are in use and the method is queued multiple times.
In your example the time to execute the callback is taking indefinitely long as it is blocking while waiting for user input.
If you want to perform such computation, I suggest you to have one independent thread that will contain a Sleep(50000) call inside. The reason is that if your computation takes more than 50 seconds you might end up with an overhead.
So in your thread measure the start time, do your computation, measure the end time, then compute the computation time and do a sleep of 50 seconds - "computation time". Ensure that this number is positive and put a 10 second minimum sleep in order to let some slack to the other tasks if the computation was longer than 40 seconds.
Thread thread = new Thread(new ThreadStart(myThreadFunction)); thread.Start();
then:
public void myThreadFunction()
{
Stopwatch stopWatch = new Stopwatch();
while(someCondition) {
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
doWork();
stopWatch.Stop();
long elapsed = stopWatch.ElapsedMilliseconds;
if(elapsed < 10000) elapsed = 10000;
Thread.Sleep(elapsed);
}
}
**doWork() does not have the ReadLine call.
System.Threading.thread.Sleep(1000); pauses a whole program for 1 second, but when this second is over it does everything what could be done for this period. For example:
Thread.Sleep(1000);
Console.WriteLine("A");
Thread.Sleep(1000);
Console.Writeline("B");
It will wait two seconds and write
A
B
How to use the pause properly?
If you want something to happen once per second, then create a timer. For example:
private System.Threading.Timer _timer;
void main()
{
_timer = new Timer(TimerTick, null, 1000, 1000);
// do other stuff in your main thread
}
void TimerTick(object state)
{
// do stuff here
}
There are several different types of timers. If you're writing a console program, then I would suggest using System.Threading.Timer. In a Windows Forms application, either System.Windows.Forms.Timer or System.Timers.Timer. See Timers for more information.
Thread.Sleep() behaves just like you would think; it just pauses the current thread for approximately the given number of milliseconds.
The problem here is that the standard output stream does not necessarily flush to the console (or wherever it is pointed at) to on each call to Write. Instead, it may buffer some content so as to write it out in larger chunks for efficiency. Try calling Console.Out.Flush(); after each WriteLine() and you should see the results you expect.