I'm currently using the System.Threading.Timer on a 10 second interval. I've adding a small piece of code to write to a file each time the timer fires, and whilst most of the time it fires on-time, sometimes (presumably when the rest of the app is buy), fails to fire for 30 or 40 seconds, and fires over and over again in quick succession.
Is there a more reliable timer I can use in .NET 3.5?
The timer is setup as follows
Timer someTimer = new Timer(new TimerCallback(SomeMethod), null, 0, 10000);
...and the callback is:
private static void SomeMethod(object state)
However, it's difficult to provide much more code than this, as the Timer usually fires correctly. When it's embedded in a massive application (~100,000 lines or so), with mulitple threads being fired off, left, right, and centre, you slowly start to see the timer firing intermitently.
I've seen several posts suggesting the ThreadPool may be exhausted, so I'm currently looking in to see if this might be what I'm experiencing.
Refer different timer classes in .net
There are three timer classes called 'Timer' in .NET. It sounds like you're using the Windows Forms one, but actually you might find the System.Threading.Timer class more useful - but be careful because it calls back on a pool thread, so you can't directly interact with your form from the callback.
More Accurate Timer - As per MSDN
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.
This sounds exactly like thread pool starvation. Look out for long running/blocking jobs running in the thread pool and either rewrite using async io, or in the case of long running CPU intensive jobs, simply don't run these jobs in the thread pool. Run them on their own thread or use a background worker.
Related
I am developing a Windows Service application, in .NET, which executes many functions (it is a WCF service host), and one of the targets is running scheduled tasks.
I chose to create a System.Threading.Timer for every operation, with a dueTime set to the next execution and no period to avoid reentrancy.
Every time the operation ends, it changes the dueTime to match the next scheduled execution.
Most of the operations are scheduled to run every minute, not all toghether but delayed by some seconds each other.
Now, after adding a number of operations, about 30, it seems that the timers start to be inaccurate, starting the operations many seconds late, or even minutes late.
I am running the operation logic directly in the callback method of the timer, so the running thread should be the same as the timer.
Should I create a Task to run the operation instead of running it in the callback method to improve accuracy?
Or should I use a single timer with a fixed (1 second) dueTime to check which operations need to be started?
I don't like this last option because it would be more difficult to handle reentrancy..
Timers fire on a thread pool thread, so you are probably finding that as you add lots of timers that you are exhausting the thread pool.
You could increase the size of the thread pool, or alternatively ensure you have fewer timers than the thread pool size.
Firing off Tasks from the callback likely won't help - since you are going to be fighting for threads from the same thread pool. Unless you use long-running tasks.
We usually setup multiple timers to handle different actions within a single service. We set the intervals and start, stop the timer on the Service Start/Stop/Shutdown events (and have a variable indicating the status for each one, i.e. bool Stopped)
When the timer ticks over, we stop the timer, run the processing (which may take a while depending on the process, i.e. may take longer than the interval if its short.. (this code needs to be in a try--catch so it keeps going on errors)
After the code has processed, we check the Stopped variable and if its not stopped we start the timer again (this handles the reentrancy that you've mentioned and allows the code to stick to the interval as much as possible)
Timers are generally more accurate after about 100ms as far as I know, but should be close enough for what you want to do.
We have run this concept for years, and it hasn't let us down.
If you running these tasks as a sub-system of an ASP.NET app, you should also look at HangFire, which can handle background processing, eliminating the need for the windows service.
How accurate do the timers need to be? you could always use a single timer and run multiple processing threads at the same time? or queue the calls to some operations if less critical.
Ok, I came to a decision: since I am not able to easily reproduce the behavior, I chose to solve the root problem and use the Service process to only:
serve WCF requests done by clients
schedule operations (which was problematic)
Every operation that could eat CPU is executed by another process, which is controlled directly by the main process (with System.Diagnostics.Process and its events) and communicates with it through WCF.
When I start the secondary process, I pass to it the PID of the main process through command line. If the latter gets killed, the Process.Exited event fires, and I can close the child process too.
This way the main service usually doesn't use much CPU time, and is free to schedule happily without delays.
Thanks to all who gave me some advices!
I've written a program which uses all available cores by using Parallel.ForEach. The list for the ForEach contains ~1000 objects and the computation for each object take some time (~10 sec).
In this scenario I setup a timer like this:
timer = new System.Timers.Timer();
timer.Elapsed += TimerHandler;
timer.Interval = 15000;
timer.Enabled = true;
private void TimerHandler(object source, ElapsedEventArgs e)
{
Console.WriteLine(DateTime.Now + ": Timer fired");
}
At the moment the TimerHandler method is a stub to make sure the problem isn't caused by this method.
My expectation was that the TimerHandler method will be executed every ~15 seconds. However, the time between two calls to this method even reaches 40 seconds, so 25 seconds too much.
By using new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount -1 } for the Parallel.ForEach method this doesn't happen and the expected interval of 15 seconds is seen.
Is it intended that I have to make sure that there is always one core available per active timer? Seems to be a bit odd even more, because the "reserved" could be a valuable resource for my computation.
Edit: As indicated by Yuval setting a fixed minimum of threads in the pool by ThreadPool.SetMinThreads solved the problem. I also tried new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount } (so without the -1 in the initial question) for the Parallel.ForEach method and this also solves the problem. However, I have no good explanation why these modifications solved the problem. Maybe there were so many threads created that the timer thread just got "lost" for a "long" time until it was executed again.
The Parallel class uses an internal TPL facility called self replicating tasks. They are meant to consume all available thread resources. I don't know what kind of limits are in place but it seems that it's all-consuming. I have answered basically the same question a few days ago.
The Parallel class is prone to spawn insane amounts of tasks without any limit. It is easy to provoke it to literally spawn unlimited threads (2 per second). I consider the Parallel class unusable without a manually specified max-DOP. It is a time bomb that explodes in production randomly under load.
Parallel is especially poisonous in ASP.NET scenarios where many requests share one thread-pool.
Update: I forgot to make the key point. Timer ticks are queued to the thread pool. If the pool is saturated they get in line and execute at a later time. (This is the reason why timer ticks can happen concurrently or after timers are stopped.) This explains what you are seeing. The way to fix that is to fix the pool overloading.
The best fix for this particular scenario would be a custom task scheduler with a fixed amount of threads. Parallel can be made to use that task scheduler. The Parallel Extension Extras have such a scheduler. Get that work off the globally shared thread pool. Normally, I would recomment PLINQ but that is not able to take a scheduler. In a sense both Parallel and PLINQ are needlessly crippled APIs.
Don't use ThreadPool.SetMinThreads. Don't mess with global process wide settings. Just leave the poor thread pool alone.
Also, don't use Environment.ProcessorCount -1 because that wastes one core.
the timer is already executed in its own thread
The timer is a data structure in the OS kernel. There is no thread until a tick must be queued. Not sure how exactly that works but the tick is queued to the thread pool in .NET eventually. That's when the problem starts.
As a solution you could start a thread that sleeps in a loop in order to simulate a timer. That's a hack, though, because it does not fix the root cause: The overloaded thread pool.
I have a background tick function that is structured as follows:
System.Threading.Thread myTimerThread = new Thread(this.Tick);
private void Tick(){
do{
//do stuff
System.Threading.Sleep(1000L);
}while(true)
}
However, there is also a System.Threading.Timer class that does this for me. What are the differences in using the built in Timer class present in System.Threading rather than creating my own background thread with a Tick function?
The Timer class would be very light weight and more efficient as compared to your own dedicated thread which is sleeping for a specified time inside infinite do while loop.
Do read Thread.Sleep is a sign of a poorly designed program for finding out how Thread.Sleep actually works and how it wastes a complete thread and resources
On the other hand System.Threading.Timer will use ThreadPool thread to execute the timer. Other benefit of using Timer class as described my MSDN
When you create a timer, you can specify an amount of time to wait before the
first execution of the method (due time), and an amount of time to wait between
subsequent executions (period). You can change these values, or disable the timer, using the Change method.
You won't have these benefits in thread based approach
First of all, use the thread pool unless you are performing a long running operation. The difference between your roll your own timer, and System.Threading.Timer is that System.Threading.Timer uses hardware interrupts to know when it is appropriate to perform the tick. It will be more accurate (though a multimedia timer will be even more accurate) than just sleeping for x milliseconds which will have to wait until control is given thread scheduler before your thread will have control.
You should also know that if you are doing anything that will affect the Gui on your thread you should use the appropriate Gui version of the timer otherwise your ticks will not occur on the thread you have to access Gui controls on and you will have to Invoke to get on the correct thread. For windows forms it is System.Windows.Forms.Timers, it is System.Windows.Threading.DispatcherTimer for WPF and Silverlight. For more information on threading and timers I highly recommend Joseph Albahari's free ebook Threading in C#.
You have alot more control using System.Threading.Timer. You can program the timer to check a certain thread or event every say....1/4 of a second, until it runs and then you can dispose of the timer using the dispose method. Its a lot more flexible because you can program it to do whatever you want and it is a lot more accurate.
When you use Thread.Sleep, you really only have one option and that is to force the program to "sleep" for x of seconds. To my knowledge you can not dispose it, time it, coordinate it so it stops early. etc. The bottom line is, even after your program is done running, the Thread.Sleep will continue to force the program to sleep. Threading.Timer can be programmed to stop when the program is finished running.
In my application I have to send periodic heartbeats to a "brother" application.
Is this better accomplished with System.Timers.Timer/Threading.Timer or Using a Thread with a while loop and a Thread.Sleep?
The heartbeat interval is 1 second.
while(!exit)
{
//do work
Thread.Sleep(1000);
}
or
myTimer.Start( () => {
//do work
}, 1000); //pseudo code (not actual syntax)...
System.Threading.Timer has my vote.
System.Timers.Timer is meant for use in server-based (your code is running as a server/service on a host machine rather than being run by a user) timer functionality.
A Thread with a While loop and Thread.Sleep command is truly a bad idea given the existance of more robust Timer mecahnisms in .NET.
Server Timers are a different creature than sleeping threads.
For one thing, based on the priority of your thread, and what else is running, your sleeping thread may or may not be awoken and scheduled to run at the interval you ask. If the interval is long enough, and the precision of scheduling doesn't really matter, Thread.Sleep() is a reasonable choice.
Timers, on the other hand, can raise their events on any thread, allowing for better scheduling capabilities. The cost of using timers, however, is a little bit more complexity in your code - and the fact that you may not be able to control which thread runs the logic that the timer event fires on. From the docs:
The server-based Timer is designed for
use with worker threads in a
multithreaded environment. Server
timers can move among threads to
handle the raised Elapsed event,
resulting in more accuracy than
Windows timers in raising the event on
time.
Another consideration is that timers invoke their Elapsed delegate on a ThreadPool thread. Depending on how time-consuming and/or complicated your logic is, you may not want to run it on the thread pool - you may want a dedicated thread. Another factor with timers, is that if the processing takes long enough, the timer event may be raised again (concurrently) on another thread - which can be a problem if the code being run is not intended or structured for concurrency.
Don't confuse Server Timers with "Windows Timers". The later usually refers to a WM_TIMER messages tha can be delivered to a window, allowing an app to schedule and respond to timed-processing on its main thread without sleeping. However, Windows Timers can also refer to the Win API for low-level timing (which is not the same as WM_TIMER).
Neither :)
Sleeping is typically frowned upon (unfortunately I cannot remember the particulars, but for one, it is an uninteruptible "block"), and Timers come with a lot of baggage. If possible, I would recommend System.Threading.AutoResetEvent as such
// initially set to a "non-signaled" state, ie will block
// if inspected
private readonly AutoResetEvent _isStopping = new AutoResetEvent (false);
public void Process()
{
TimeSpan waitInterval = TimeSpan.FromMilliseconds (1000);
// will block for 'waitInterval', unless another thread,
// say a thread requesting termination, wakes you up. if
// no one signals you, WaitOne returns false, otherwise
// if someone signals WaitOne returns true
for (; !_isStopping.WaitOne (waitInterval); )
{
// do your thang!
}
}
Using an AutoResetEvent (or its cousin ManualResetEvent) guarantees a true block with thread safe signalling (for such things as graceful termination above). At worst, it is a better alternative to Sleep
Hope this helps :)
I've found that the only timer implementation that actually scales is System.Threading.Timer. All the other implementations seem pretty bogus if you're dealing with a non trivial number of scheduled items.
I want to ask if a System.Timers.Timer instance runs on a single thread, a thread pool, or something else?
If it does run on a single thread, what do you think would be best for this example:
I want to update all character's health every minute
I want to update all character's energy every 2 seconds
I want to update all character's specials every 40 seconds
Should I run them each on a separate thread, run them on a separate event, or run all of those in a single thread having to check the time differences?
I would run all the actions from a single timing thread and compute the time differences. This way I would be able to run as many actions as I would like without instantiating more timers.
It's also easier to synchronize actions which occur at the same time interval.
From http://msdn.microsoft.com/en-us/library/system.timers.aspx:
The server-based Timer is designed for
use with worker threads in a
multithreaded environment. Server
timers can move among threads to
handle the raised Elapsed event,
resulting in more accuracy than
Windows timers in raising the event on
time.
System.Timers.Timer elapsed event uses Threadpool. So multiple threads can be invoked if the interval is less( and elapsed event> interval takes long time to complete). Threadpool runs in background and UI updates cannot be done outside the UI thread in windows application. You can however use Control.Invoke Control.BeginInvoke
Link
Timers
difference between invoke and begininvoke
Should I run them each on a separate thread, run them on a separate event, or run all of those in a single thread having to check the time differences.
In my opinion you should use three timers. Three is a number which should not affect the performance in a negative way.
A big disadvantage when calculating time differences are time-changes (daylight saving times, synchronisation with the Internet).
You would have to use Environment.TickCount.