Timer Interval Increases when CPU utilization and memory increases - c#

I have a Timer in my code for some 'x' seconds. The code has multiple threads and there are multiple timers. Now I notice that, my application goes to a hang state after running for some time and from the logs I notice that the timer interval varies. It has increased. How is this possible and can anyone provide a solution for this? Is there any alternative for timer in c#
_timernew = new System.Timers.Timer(10000)
{
AutoReset = false
};
_timernew .Elapsed += (sender, e) => { DoSomething };
_timernew .Enabled = true;

Timers are not precise. The interval is the minimum delay before the event is fired, but you are not guaranteed your timer event will get executed exactly when the interval elapses.
When the interval elapses, the timer queues your even handler to the thread pool. Therefore, the event handler will get executed when there is an available thread in the threadpool to take the handler, and then an available CPU core to actually execute it.
In other words, the more busy the computer is, the more likely delays will happen.
If you need a closer to real-time execution, you must use a dedicated thread and set its priority to high:
Thread myThread = new Thread(MyThreadMethod);
myThread.Priority = ThreadPriority.Highest;
myThread.Start();
Now, however, in your MyThreadMethod, you need to implement a sophisticated mechanism that monitors how much time has elapsed and decide whether you must execute your actual code or not.
You should not just loop and check the time, because that will occupy a single core at 100%. Perhaps you can use the dreaded Thread.Sleep with a smaller interval and check if time has passed. You must use a smaller interval than the one you need at a magnitude of at least 10. Thread.Sleep is not precise, too.

Related

Thread Sleep by name or some any other method

is there anyway to sleep the some particularthread by name or some any other source
in case I've two threads
Thread call = new Thread(() => open_page(txtbx_1.Text));
call.Start();
Thread call_2nd = new Thread(() => open_page(txtbx_1.Text));
call_2nd.Start();
I want to sleep call and call_2nd for at least 15 minutes(but don't want to sleep the main Thread.
Thanks
No - you can't ask another thread to sleep. Apart from anything else, at the time when you want it to sleep it may hold a lock or other resource which really shouldn't be held while sleeping.
You'd have to do this cooperatively, with some sort of shared data between the threads indicating what you want to sleep and for how long. Alternatively, schedule a timer to only start the relevant activity after a certain length of time.
Why would you want a thread to sleep unless it was otherwise going to do something you didn't want it to do? And why would you ever code a thread to do something you didn't want to do?
If you're asking this question, something is very wrong somewhere in your design or implementation.
Yes, but in a different way than you might think.
Have the target thread(s) you want to sleep regularly check an manual-reset event. That event (flag) is cleared by the controlling thread whenever the target thread is supposed to sleep, otherwise it is always set. If you want the target thread(s) to sleep only for a certain amount of time, use that value as the wait timeout.
if the event is set (no sleep), the wait is satisfied immediately and execution continues
if the event is cleared (sleep), the target thread(s) stops until
the timeout (15 minutes = 15 * 60 * 1000 ms) elapsed
or the controlling thread sets the event again within that time frame
If you need to check whether or not the target thread(s) is in the waiting state, consider another event/flag/counter, set by the target thread(s), and read by the controlling thread.

Alternative to SpinWait.SpinUntil

We are using Task in our application. In one class we want to trigger an update that is running on a parallel task. The call looks like:
Maintenance.RecievedMessage += new NotificationHandler(Maintenance_RecievedMessage);
Maintenance.checkLastXML = false;
Maintenance.NeedToUpdateFromCarrier(userId);
SpinWait.SpinUntil(() => isCompleted == true);
return true;
So we hook up an event that is triggered when the Maintenance.NeedToUpdateFromCarrier(userId);
method is done running. The complete method looks like:
private void Maintenance_RecievedMessage(IsCompleted changeargs)
{
isCompleted = true;
}
So we are waiting for the NeedToUpdateFromCarrier method, as soon as it's done it triggers the event that its done, and we catch the event and set the property isComplete to true, and thats when the SpinWait.SpinUntil finnaly is done, and we continue.
Since SpinWait.SpinUntil is very heavy for the CPU, I'm now looking for an alternative solution to this problem.
It is important to understand when spin-waiting is appropriate. There are very few cases where it is. Spin-waiting optimizes thread context switching. Whenever you wait for something, a call like WaitHandle.Wait() will block the thread and yield the processor. The operating system performs a thread context switch when it finds some other thread to perform useful work.
Thread context switches are pretty expensive. There's no exact number because it depends on where the yield-to thread runs, there's extra overhead when that thread runs in another process or protection ring (drivers). It costs between 2000 and 10,000 cycles.
Those are cpu cycles that don't accomplish much. Just overhead that doesn't get real work done. You can optimize your threading code if you know that it always takes less than 20,000 cycles for the wait condition to be met. Just delaying your thread (spinning) will then ensure that the expensive context switching isn't needed. This is not the normal kind of delay like Thread.Sleep(), that yields, it is small loop that burns 100% core. With a few smarts thrown in, like spinning on a machine with only one core will never work well so it yields anyway.
Clearly this will not work well if the wait condition consistently takes more than 20,000 cycles. Now you're on the other end of the wise choice, you do want to yield in those cases. Not just to avoid burning cpu when it doesn't accomplish anything but especially so because yielding makes it now more likely that the wait condition will be met sooner. Because you increase the odds that the thread that sets the wait condition can get enough cpu cycles to finish its job.
There's plenty of evidence that's the case in your code. You explicitly ask code to do something before spinning. And it requires an event handler to signal the completion. Mucho code needs to run. And most convincingly, you are seeing lots of cpu being burned. 1% of load in TaskMgr.exe is about 20 million cpu cycles.
Use a waitable event instead, like AutoResetEvent. Note the structural change required, isCompleted can't be a bool anymore. You call Set() in the completion handler, Wait() to block on it.
You can use a ManualResetEventSlim:
var signal = new ManualResetEventSlim();
Maintenance.RecievedMessage += delegate { signal.Set(); };
Maintenance.checkLastXML = false;
Maintenance.NeedToUpdateFromCarrier(userId);
signal.Wait();
return true;

C#: What if System.Windows.Forms.Timer interval was not enough for doing a job?

First, sorry for my bad english writing.
Suppose that we have a win form (C#) that has a timer. The timer interval has been set to 60000 milsec. So its tick event will be fired every 1 milute. Suppose we have written a method that handles tick event called Timer1_Tick. What if the job needs more that 1 minute to complete?
You've got several options, here's four I can think of:
Abandon the current job to start the new one. The big downside of this one is, of course, if the current job can't be stopped.
Wait for the current job to finish before starting the new one. This might leave you with a queue of pending jobs if each one takes more than a minute.
Don't start the new job. Let the current one finish and then wait for the next timer interval to start the new job.
Increase the interval between jobs. This is just putting off the problem.
There is no right answer. You'll have to work out what's best and works for your situation.
I'd go for #3 as my first solution.
Setup a flag that will allow you to check if the long running job has finished and only run the job if it has finished. Don't forget to reset the flag after finishing the long running job:
// field
private bool finishedWork = true;
public void Timer1_Tick(Object o, EventArgs e)
{
if (finishedWork)
{
finishedWork = false;
// do work
finishedWork = true;
}
}
Another option is to simply disable the timer between operations:
public void Timer1_Tick(Object o, EventArgs e)
{
if (finishedWork)
{
Timer1.Enabled = false;
// do work
Timer1.Enabled= true;
}
}
So set a flag when you start the job and check the flag when the timer fires. If the flag is set, do nothing in the timer handler. Remember to clear the flag when the job completes.
Are you spinning off a worker thread to do the job?
Another timer event will likely be queued, causing Timer1_Tick to be called again almost immediately after it returns. (IIRC, though, timer ticks are one of the lowest priority messages, so it'll probably handle any other messages it's had queued up to that point first, except maybe paint messages).
Note, if your function takes longer than 2 minutes to run, it's possible (read: likely) that only the latest tick will be in the queue.
If your tick processing takes longer than the timer interval, you should look into raising the interval. Either way, you should probably be doing the work in a background thread and making sure you don't start another thread if the last tick's task isn't done. Otherwise you could end up with hordes of threads all slowing each other down til your program collapses under its own weight.
Store the current state of the process in a field or property and start the process only if the state is no "running".
Disable the timer at the start of Timer1_Tick and then enable it again afterwards?
There are multiple types of Timers in .Net: One is in a System.Timers namespace, another is in System.Windows.Forms namespace and another in System.Threading.
The System.Windows.Forms.Timer control is based on UI thread and message loops, meaning it will queue the timer events and if your handler exceeds the interval, it will be called immediately after ending.
The other two timers are based on threading, and are very accurate. They will reenter you handler after the time elapsed.

Timer takes 10 ms more than interval

I am using a timer with interval 1 second.
But in the timer's tick event when I print the time it's always 62 or 65 ms.
I don't understand why it's taking 10 ms more.
Please can some one have look into this.
Here is the code I am using:
static int _counter;
var _timer = new System.Timers.Timer(1000);
public Form1()
{
InitializeComponent();
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Start();
}
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine(DateTime.Now.ToString("{hh:mm:ss.fff}"));
_counter++;
if (_counter == 20)
_timer.Stop();
}
And this the output:
{01:59:08.381}
{01:59:09.393}
{01:59:10.407}
{01:59:11.421}
{01:59:12.435}
{01:59:13.449}
{01:59:14.463}
{01:59:15.477}
{01:59:16.491}
{01:59:17.505}
{01:59:18.519}
{01:59:19.533}
{01:59:20.547}
{01:59:21.561}
{01:59:22.575}
{01:59:23.589}
{01:59:24.603}
{01:59:25.615}
{01:59:26.629}
{01:59:27.643}
You need to understand that Windows is not a real-time operating system. Real-time operating systems have timer mechanisms that allow the system to make hard guarantees about when timer-initiated events occur and the overhead associated with them, and allow you to specify what behavior should occur when the deadline is missed -- for example if the previous execution took longer than the interval.
I would characterize the Windows timers as "best effort" when it comes to smaller intervals. When the interval is sufficiently long you don't notice that you aren't getting the exact interval that you requested. As you get closer and closer to the resolution of the timer (the frequency at which the timer runs), you start seeing the overhead as a percentage of the interval increase. Real-time systems take special care to minimize the software overhead, relying on more sophisticated and faster hardware solutions. The exact frequency of the Windows timer depends on the timing services that the underlying hardware provides and so may differ from system to system.
If you have real-time needs -- and doing something every 50ms may fall into that category -- then you may need to look at specialized hardware and/or a real-time OS.
It's because of the limited resolution of the system clock. The event occurs at the next system tick after the specififed time, so you will always get a few extra milliseconds.
If you need a more precise timer, you can hook into the Win32 Multimedia Timer, it is the most accurate timer (down to 1ms). Here's an article on CodeProject showing how to hook into it from C#.
First, as other people have noted, you're setting it to 1s, not 50ms.
Secondly, windows is not a real-time OS. None of the timer classes are exactly precise. All you're doing it saying that you want to wait at least this long. It takes some amount of time for everything to fire and you to end up notified that the timer has ticked once windows gets around to actually servicing the tick message.
Note that usually, in most language, sleep calls specify the minimum time after which a process would awaken. After the specified time has passed, the process is put on a queue and hopefully the scheduler activates it. But this activation may sometimes be delayed. I'm not sure about the Timer class, but I suspect it may suffer from a similar problem.
You may perhaps try to increase the priority of your process to cut down the increased time.
System.Timers.Timer is not a precise timer. Especially when system is under load it can have even bigger delays.
Also to get better accuracy in your example change time measuring code to use Stopwatch class.
static int _counter;
System.Timers.Timer _timer = new System.Timers.Timer(1000);
Stopwatch sw;
public Form1()
{
InitializeComponent();
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Start();
sw = Stopwatch.StartNew();
}
void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine(sw.ElapsedMilliseconds);
_counter++;
if (_counter == 20)
_timer.Stop();
sw.Reset();
sw.Start();
}
Using the system timers will always be a little longer than the value requested. This is due to the overhead of the other processes in the system.
On my system it's 14ms. Having googled; the difference is down to context thread switching delay. There's an article regarding high resolution timers here
As other responders have mentioned, Windows is not a real-time OS. If you must use windows, try using Win CE or Windows Embedded.
-S!
The accuracy of the time may depend on how many processes run. If you have that option , I would reduce the number of processes that run on your computer one by one and I mean those which consume significant cpu time,I would check if the times improve. Especially, browsers, virus scanners,programs running in the background.
The deviations are normal since they are not RTOS (real time operating systems). This is the best solution that I've found under the circumstances: Link
Program.MicroTimer microTimer = new Program.MicroTimer();
microTimer.MicroTimerElapsed += new Program.MicroTimer.MicroTimerElapsedEventHandler(OnTimedEvent);
microTimer.Interval = 1000; // Call micro timer every 1000µs (1ms)
// Can choose to ignore event if late by Xµs (by default will try to catch up)
// microTimer.IgnoreEventIfLateBy = 500; // 500µs (0.5ms)
microTimer.Enabled = true; // Start timer
System.Threading.Thread.Sleep(2000);
microTimer.Enabled = false;
Those are the code snippets. You can try them to see the values in the console.

What happens with timer tick after wake up from stand-by?

My C#-programm has a windows.forms.timer that fires all 24h for a background task.
During a day I put my Vista 64bit several times in stand-by mode (never switch it off).
It seems that after wake-up the timer is sort of reset.
Your timer shouldn't be set to fire every 24 hours, it should be set to fire every few seconds, or minutes, and check the time. If the time is greater than, or equal to, the time you want your task to occur, perform the task.
The Timer class is very relaxed about raising its Tick event. Internally, inside the Windows code, when the timer is due it only sets an internal flag, somewhat akin to "ought to deliver WM_TIMER". That doesn't actually happen until nothing important needs to be done by the message loop. Any message gets higher priority than WM_TIMER.
When the Windows Forms message loop calls GetMessage(), the function checks if anything needs to be returned. If the answer is "nothing" and the flag is set, it supplies WM_TIMER. And you'll get the Tick event.
A couple of consequences from that: you can never use the Tick event to keep track of time. That will inevitably fall behind. You can never get the Tick event twice in a row, it doesn't catch up. But relevant to your question: the message loop isn't pumping when the machine goes in stand-by, nothing special happens.
During standby, typically memory is stored as-is, then recalled when you wake the machine, which might cause your timer to either not tick during the stand-by, or have imprecise behavior from what you intend.

Categories