Reliable alternative to Timer in .NET framework? - c#

Is there relialbe alternative to Timer class in .Net?
We are having issues with System.Timers.Timer and System.Threading.Timer, e.g., they start immidietly, or sometimes fire out after long period of inactivity (after 49 days).
I've seen that there seems to be a lot of issues with them like here: http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/dbc398a9-74c0-422d-89ba-4e9f2499a6a3
We can not use Forms timer.
We are thinking to pause the thread for certain period of time instead of the timer...

This article describes the difference between the timer classes in the .Net framework.
But maybe another approach can help:
If have have to wait for such a long time it would be better to calculate the DateTime when you like something to start. Afterwards your task wakes up every second (or whatever accuracy is needed) and compares the current time with the desired time. If the current time is equal or greater just start your job. Otherwise go to sleep (till the next second, hour, millisecond, whatever). By the way, that's the way how the Microsoft Task Scheduler works.

I think you need System.Diagnostics.Stopwatch.
The Stopwatch measures elapsed time by counting timer ticks in the underlying timer mechanism. If the installed hardware and operating system support a high-resolution performance counter, then the Stopwatch class uses that counter to measure elapsed time. Otherwise, the Stopwatch class uses the system timer to measure elapsed time. Use the Frequency and IsHighResolution fields to determine the precision and resolution of the Stopwatch timing implementation.

You could replace the timer with a new instance every 48 days in the Tick/Elapsed event handler.
The threading will most likely work, but is it going to be worth the extra overhead?

I'm also aware of those limitations and have implemented an own timer. Sucked to take that decision, but I have not regretted it so far. As a bonus my own timer implements an interface so that classes using the timer can be unit-tested easily.
Some .NET timers also has a problem where they may invoke the callback before the last callback has finished.
I would recommend putting the timer logic in it's own class rather than pausing a thread.

Related

Does WaitHandle.WaitOne() include time hibernated/sleeping?

In .NET, does WaitHandle.WaitOne(int millisecondsTimeout) (and presumably methods that block with timeouts, such as Thread.Sleep()) include time that the computer is hibernating or sleeping? For example, if I call WaitHandle.WaitOne(600000) to timeout in ten minutes, the computer hibernates for 5 of those minutes, will it timeout 10 minutes after calling or 15 minutes after calling?
My goal is to have it not include time spent during hibernation or sleeping.
Since Windows 7, kernel32.dll has a QueryUnbiasedInterruptTime function.
The unbiased interrupt-time count does not include time the system spends in sleep or hibernation.
The remarks provide pretty conclusive evidence that ordinary waits and timers do count time spent suspended:
The interrupt-time count retrieved by the QueryUnbiasedInterruptTime function reflects only the time that the system is in the working state. Therefore, the interrupt-time count is not "biased" by time the system spends in sleep or hibernation. The system uses biased interrupt time for some operations, such as ensuring that relative timers that would have expired during sleep expire immediately upon waking.
You will probably need p/invoke to call it from C# since I've never heard of any .NET base class library approach to doing it.
It doesn't put your thread to sleep by itself, you'll have to call it before and after the synchronizing sleep and calculate how much sleep time you still need (in case you lost some due to power savings) and then return to sleep again with the new timeout. Repeat in a loop until you actually sleep for as much CPU time as desired.
If you're using async code, there's no reason you couldn't use this function also for recalibration of Task.Delay, which you call in a loop. CancellationTokenSource.CancelAfter is a bit more problematic, since you can't uncancel if your calculation reveals you need to adjust the timeout. So you'd have to separately sleep and cancel the token yourself, without the help of scheduled cancellation.
Finally, if you're trying to set a timeout to happen after some other process has had a chance to do a certain amount of work, regardless of the passage of wall-clock time, you should be using resource limits on a Job object. The Job object measures CPU time actually spent by a particular process and is unaffected by time the process isn't working, whether due to suspend, being preempted by higher priority tasks, etc.

Inconsistent intervals with System.Windows.Forms.Timer

Please be kind, I'm just learning C# and inheriting this application from a former-employee is my first C# project.
I am observing inconsistent and slow periods with System.Windows.Forms.Timer. The application is written in C# with MS Visual Studio.
The timer is set for an interval of 100 msec yet I am observing periods ranging from 110 msec to 180 msec.
I am using several tools to observe this including:
- a SW oscilloscope (the Iocomp.Instrumentation.Plotting.Plot package),
- a real oscilloscope,
- letting the timer run for some time and comparing the number of ticks * 100 msec to both the system time and to a stopwatch.
In all cases I am observing a 10% lag that becomes evident within the first few seconds.
The methods that are executed with each tick take fewer than 4 msec to run. There is no time-consuming asynchronous processing happening, either. This shouldn't matter, though, as the timer tick is an interrupt, not an event added to an event handler queue (as far as I know).
Has anyone experienced a problem like this before? What were the root causes?
Thanks.
Timers are only as accurate as the operating system clock interrupt. Which ticks 64 times per second by default, 15.625 msec. You cannot get a clean 100 msec interval from that, it isn't divisible by 15.625. You get the next integer multiple, 7 x 15.625 = 109.375 msec. Very close to the 110 msec you observed.
You need to add the latency in the handling of the timer notification to this theoretical minimum. Timers have to compete with everything else that's going on in your UI thread. They are treated as the least important notification to be delivered. Sent messages go first, user input goes next, painting is next, timer messages are last. Either way, if you have an elaborate user interface that takes a while to repaint then the Tick event is going to be delayed until that's done. Same for any event handler you write that does something non-trivial like reading a file or querying a dbase.
To get a more responsive timer that doesn't suffer from this kind of latency, you need to use an asynchronous timer. System.Threading.Timer or System.Timers.Timer. Avoid the latter. Their callback runs on a threadpool thread so can get running pretty quickly. Be very careful what you do in this callback, lots of things you cannot do because they are not thread-safe.
You can these timers more accurate by changing the clock interrupt rate. That requires pinvoke, call timeBeginPeriod(). timeEndPeriod() when you're done.
Yes,I always faced this issue with System.Windows.Forms.Timer as it doesnt ticks accurately(most of the time).
You can try System.Timers.Timer instead and it raises interrupt precisely(atleast for 100ms precision)
System.Windows.Forms.Timer is really just a wrapper for the native WM_TIMER message. this means that the timer message is placed in the message queue at time roughly close to the interval you requested (plus or minus... there's no guarantee here). when that message is processed is entirely dependant on other messages in the queue and how long each takes to process. For example, if you block the UI thread (and thus block the queue from processing new messages) you won't get the timer event until after you unblock.
Windows is not a real-time operating system, you can't expect fine-grained accuracy in timers. If you want something more fine-grained, a multimedia timer is the best choice.
This is old, but in case anyone comes here looking for an actually correct answer:
From https://msdn.microsoft.com/en-us/library/system.windows.forms.timer(v=vs.110).aspx (emphasis mine):
The Windows Forms Timer component is single-threaded, and is limited to an accuracy of 55 milliseconds. If you require a multithreaded timer with greater accuracy, use the Timer class in the System.Timers namespace.
So with Windows.Forms.Timer you can get 55ms, 110ms, 165ms, etc.; which is consistent with what you were seeing. If you need higher precision, try System.Timers.Timer or System.Threading.Timer

Using Timers to create a single timeout frequently

I'm working with a timeout which is set to occur after a certain elapsed period, after which I would like to get a callback. Right now I am doing this using a Timer that when fired disposes of itself.
public class Timeouter
{
public void CreateTimeout(int timeout, Action onTimeout)
{
Timer t = null;
t = new Timer(_ =>
{
onTimeout();
t.Dispose();
}, new object(), timeout, Timeout.Infinite);
}
}
I'm a bit concerned regarding the resource use of this timer since it could potentially be called quite frequently and would thus setup a lot of timers to fire just once and dispose of themselves. Considering that the timer is an IDisposable it would indicate to me that it indeed uses some sort of expensive resource to accomplish its task.
Am I worrying too much about the resource usage of the Timer, or perhaps the solution is fine as it is?
Do I have any other options for doing this? Would it be better to have a single timer and fiddling with it's frequency starting and stopping it as necessary in order to accommodate several of these timeouts? Any other potentially more lightweight option to have a task execute once after a given period of time has elapsed?
.Net has 2 or 3 timer classes which are expensive. However the System.Threading.Timer class which you're using is a very cheap one. This class do not use kernel resources or put a thread to sleep waiting for timeout. Instead it uses only one thread for all Timer instances, so you can easily have thousands of timers and still get a tiny processor and memory footprint. You must call Dispose only because you must notify the system to stop tracking some timer instance, but this do not implies that this is a expensive class/task at all.
Once the timeout is reached this class will schedule the callback to be executed by a ThreadPool thread, so it do not start a new thread or something like this.
Though its not an answer, but due to length I added it as answer.
In a server/Client environment, AFAIK using Timers on server is not the best approach, rather if you have thick clients or even thin clients, you should devise some polling mechanism on client if it wants a certain operation to be performed on the server for itself(Since a client can potentially disconnect after setting up a timer and then reinstantiate and set a timer again an so on, causing your server to be unavailable at sometime in future(a potential DOS attack)),
or else think of a single timer strategy to deal with all clients, which implements sliding expirations or client specific strategies to deal with it.
one other option is to maintain a sorted list of things which will timeout, add them to the list with their expiry time instead of their duration, keep the list sorted by the expiry time and then just pop the first item off the list when it expires.
You will of course need to most of this on a secondary thread and invoke your callbacks. You don't actaully need to keep the thread spinning either, you could set a wait handle on the add method with a timeout set for (a bit less than) the duration until the next timeout is due. See here for more information on waiting with a timeout.
I don't know if this would be better than creating lots of timers.
Creating a cheap timer that can time many intervals is intuitively simple. You only need one timer. Set it up for the closest due time. When it ticks, fire the callback or event for every timer that was due. Then just repeat, looking again through the list of active timers for the next due time. If a timer changes its interval then just repeat the search again.
Something potentially expensive might happen in the callback. Best way to deal with that is to run that code on a threadpool thread.
That's extraordinarily frugal use of system resources, just one timer and the cheapest possible threads. You pay for that with a little overhead whenever a timer's state changes, O(n) complexity to look through the list of active timers, you can make most of it O(log(n)) with a SortedList. But the Oh is very small.
You can easily write that code yourself.
But you don't have to, System.Timers.Timer already works that way. Don't help.

Heartbeat implementation with Thread.Sleep()

in my application I have an "heartbeat" functionality that is currently implemented in a long running thread in the following way (pseudocode):
while (shouldBeRunning)
{
Thread.Sleep(smallInterval);
if (DateTime.UtcNow - lastHeartbeat > heartbeatInterval)
{
sendHeartbeat();
lastHeartbeat = DateTime.UtcNow;
}
}
Now, it happens that when my application is going through some intensive CPU time (several minutes of heavy calculations in which the CPU is > 90% occupied), the heartbeats get delayed, even if smallInterval << heartbeatInterval.
To crunch some numbers: heartbeatInterval is 60 seconds, lastHeartbeat is 0.1 seconds and the reported delay can be up to 15s. So, in my understanding, that means that a Sleep(10) can last like a Sleep(15000) when the CPU is very busy.
I have already tried setting the thread priority as AboveNormal - how can I improve my design to avoid such problems?
Is there any reason you can't use a Timer for this? There are three sorts you can use and I usually go for System.Timers.Timer. The following article discusses the differences though:
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx
Essentially timers will allow you to set up a timer with a periodic interval and fire an event whenever that period ticks past. You can then subscribe to the event with a delegate that calls sendHeartbeat().
Timers should serve you better since they won't be affected by the CPU load in the same way as your sleeping thread. It has the advantage of being a bit neater in terms of code (the timer set up is very simple and readable) and you won't have a spare thread lying around.
You seem to be trying to reinvent one of the timer classes.
How about using System.Timers.Timer for example?
var timer = new System.Timers.Timer(smallInterval);
timer.Elapsed += (s, a) => sendHeartbeat;
timer.Enabled = true;
One of the issues here may be, at a guess, how often your thread gets scheduled when the CPU is under load. Your timer implementation is inherently single threaded and blocks. A move to one of the framework timers should alleviate this as (taking the above timer as an example) the elapsed event is raised on a thread pool thread, of which there are many.
Unfortunately, Windows is not a Real Time OS and so there are few guarantees about when threads are executed. The Thread.Sleep () only schedules the earliest time when the thread should be woken up next, it is up to the OS to wake up the thread when there's a free time slice. The exact criteria for waking up a sleeping thread is probably not documented so that the Window's kernel team can change the implementation as they see fit.
I'm not sure that Timer objects will solve this as the heartbeat thread still needs to be activated after the timer has expired.
One solution is to elevate the priority of the heartbeat thread so that it gets a chance of executing more often.
However, heartbeats are usually used to determine if a sub-system has got stuck in an infinite loop for example, so they are generally low priority. When you have a CPU intensive section, do a Thread.Sleep (0) at key points to allow lower priority threads a chance to execute.

Best way to check when a specified date occurs

Are there any classes in the .NET framework I can use to throw an event if time has caught up with a specified DateTime object?
If there isn't, what are the best practices when checking this? Create a new thread constantly checking? A timer (heaven forbid ;) )?
I wouldn't go with the thread approach. While a sleeping thread doesn't consume user CPU time, it does use Kernel/system CPU time. Secondly, in .NET you can't adjust the Thread's stack size. So even if all it does is sleep, you are stuck with a 2MB hit (I believe that is the default stack size of a new thread) for nothing.
Using System.Threading.Timer. It uses an efficient timer queue. It can have hundreds of timers that are lightweight and only execute on 1 thread that is reused between all timers (assuming most timers aren't firing at the same time).
When a thread is sleeping it consumes no CPU usage. A very simple way would be to have a thread which sleeps until the DateTime. For example
DateTime future = DateTime.Now.Add(TimeSpan.FromSeconds(30));
new Thread(() =>
{
Thread.Sleep(future - DateTime.Now);
//RaiseEvent();
}).Start();
This basically says, get a date in the future (thirty seconds from now). Then create a thread which will sleep for the difference of the times. Then raise your event.
Edit: Adding some more info about timers. There is nothing wrong with timers, but I think it might be more work. You could have a timer with an interval of the difference between the times. This will cause the tick event to fire when the time has caught up to the date time object.
An alternative, which I would not recommend, and I seem to think you have though of this, is to have a timer go off every five seconds and check to see if the times match. I would avoid that approach and stick with having the thread sleep until there is work to be done.
A timer is probably not a bad way to go. Just use DateTime.Now to detect if it's over the target time. Don't use == unless you try to normalize the times to the minute or the hour or something.

Categories