Using Timers to create a single timeout frequently - c#

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.

Related

Thread.Sleep() usage to Prevent Server Overload

I wrote some code that mass imports a high volume of users into AD. To refrain from overloading the server, I put a thread.sleep() in the code, executed at every iteration.
Is this a good use of the method, or is there a better alternative (.NET 4.0 applies here)?
Does Thread.Sleep() even aid in performance? What is the cost and performance impact of sleeping a thread?
The Thread.Sleep() method will just put the thread in a pause state for the specified amount of time. I could tell you there are 3 different ways to achieve the same Sleep() calling the method from three different Types. They all have different features. Anyway most important, if you use Sleep() on the main UI thread, it will stop processing messages during that pause and the GUI will look locked. You need to use a BackgroundWorker to run the job you need to sleep.
My opinion is to use the Thread.Sleep() method and just follow my previous advice. In your specific case I guess you'll have no issues. If you put some efforts looking for the same exact topic on SO, I'm sure you'll find much better explanations about what I just summarized before.
If you have no way to receive a feedback from the called service, like it would happen on a typical event driven system (talking in abstract..we could also say callback or any information to understand how the service is affected by your call), the Sleep may be the way to go.
I think that Thread.Sleep is one way to handle this; #cHao is correct that using a timer would allow you to do this in another fashion. Essentially, you're trying to cut down number of commands sent to the AD server over a period of time.
In using timers, you're going to need to devise a way to detect trouble (that's more intuitive than a try/catch). For instance, if your server starts stalling and responding slower, you're going to continue stacking commands that the server can't handle (which may cascade in other errors).
When working with AD I've seen the Domain Controller freak out when too many commands come in (similar to a DOS attack) and bring the server to a crawl or crash. I think by using the sleep method you're creating a manageable and measurable flow.
In this instance, using a thread with a low priority may slow it down, but not to any controllable level. The thread priority will only be a factor on the machine sending the commands, not to the server having to process them.
Hope this helps; cheers!
If what you want is not overload the server you can just reduce the priority of the thread.
Thread.Sleep() do not consume any resources. However, the correct way to do this is set the priority of thread to a value below than Normal: Thread.Current.Priority = ThreadPriority.Lowest for example.
Thread.Sleep is not that "evil, do not do it ever", but maybe (just maybe) the fact that you need to use it reflects some lack on solution design. But this is not a rule at all.
Personally I never find a situation where I have to use Thread.Sleep.
Right now I'm working on an ASP.NET MVC application that uses a background thread to load a lot of data from database into a memory cache and after that write some data to the database.
The only feature I have used to prevent this thread to eat all my webserver and db processors was reduce the thread priority to the Lowest level. That thread will get about to 35 minutes to conclude all the operations instead of 7 minutes if a use a Normal priority thread. By the end of process, thread will have done about 230k selects to the database server, but this do not has affected my database or webserver performance in a perceptive way for the user.
tip: remember to set the priority back to Normal if you are using a thread from ThreadPool.
Here you can read about Thread.Priority:
http://msdn.microsoft.com/en-us/library/system.threading.thread.priority.aspx
Here a good article about why not use Thread.Sleep in production environment:
http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx
EDIT Like others said here, maybe just reduce your thread priority will not prevent the thread to send a large number of commands/data to AD. Maybe you'll get better results if you rethink all the thing and use timers or something like that. I personally think that reduce priority could resolve your problem, although I think you need to do some tests using your data to see what happens to your server and other servers involved in the process.
You could schedule the thread at BelowNormal priority instead. That said, that could potentially lead to your task never running if something else overloads the server. (Assuming Windows scheduling works the way the documentation on scheduling threads mentions for "some operating systems".)
That said, you said you're moving data into AD. If it's over the nework, it's entirely possible the CPU impact of your code will be negligible compared to I/O and processing on the AD side.
I don't see any issue with it except that during the time you put the thread to sleep then that thread will not be responsive. If that is your main thread then your GUI will become non responsive. If it is a background thread then you won't be able to communicate with it (eg to cancel it). If the time you sleep is short then it shouldn't matter.
I don't think reducing the priority of the thread will help as 1) your code might not even be running on the server and 2) most of the work being done by the server is probably not going to be on your thread anyway.
Thread.sleep does not aid performance (unless your thread has to wait for some resource). It incurs at least some overhead, and the amount of time that you sleep for is not guaranteed. The OS can decide to have your Thread sleep longer than the amount of time you specify.
As such, it would make more sense to do a significant batch of work between calls to Thread.Sleep().
Thread.Sleep() is a CPU-less wait state. Its overhead should be pretty minimal. If execute Thread.Sleep(0), you don't [necessarily] sleep, but you voluntarily surrender your time slice so the scheduler can let lower priority thread run.
You can also lower your thread's priority by setting Thread.Priority.
Another way of throttling your task is to use a Timer:
// instantiate a timer that 'ticks' 10 times per second (your ideal rate might be different)
Timer timer = new Timer( ImportUserIntoActiveDirectory , null , 0 , 100 ) ;
where ImportUserIntoActiveDirectory is an event handler that will import just user into AD:
private void ImportUserIntoActiveDirectory( object state )
{
// import just one user into AD
return
}
This lets you dial things in. The event handler is called on thread pool worker threads, so you don't tie up your primary thread. Let the OS do the work for you: all you do is decide on your target transaction rate.

.Net app thread/timer performance

I'm developing an app that starts a System.Threading.Timer which does some fairly rapid reading/writing to the serial port (every 100ms). The timer's callback method looks something like this:-
if (_timerTaskRunning)
{
Debug.WriteLine("still running");
return;
}
_timerTaskRunning = true;
... do the serial write/read here ...
_timerTaskRunning = false;
The _timerTaskRunning flag is a safeguard to ensure that the delegate doesn't run if the previous timer "cycle" hasn't finished, i.e. it's taking longer than 100ms.
When I first start the app I see around a dozen debug messages from the if statement. It'll then settle down but I see another group of messages 7 or 8 seconds later. It settles down again, and every once in a while I'll see a group of messages appear in varying numbers.
I'm assuming the first group of messages are caused by the timer delegate running slowly due to the app still starting up, objects/UI initialising, etc, etc, while subsequent messages are perhaps caused by garbage collection kicking in every so often and slowing things down? It's not the serial port because I see the same behaviour with a "mock" serial port.
I've tried delaying the timer's first run by a couple of seconds but it makes no difference - I still get a batch of debug messages for the first second or so after the timer starts. It's not the end of the world skipping some of the timer tasks but it would be interesting to know what might be causing them. Is there anything I can do to investigate the cause further, e.g. would perfmon shed any light on things? I haven't used it before so which counters would you suggest?
It sounds like you have a reentrancy problem. Basically your _timerTaskRunning isn't working as a safeguard likely due to race conditions.
Use System.Timers.Timer instead of System.Threading.Timer
Set Timer.AutoReset to false. This will fix your entrancing problem because it won't call you call back until you explicitly want it to.
Call Start() on your timer when you need it to go again (you may need to adjust the interval to account for execution time)
If you have multiple threads that can call start you will need to synchronize the calls to it.
Your _timerTaskRunning gets updated by several threads. You need to use locking to make it thread-safe.
However, I would not use a timer at all. I have implemented a non-renetrant timer here. It uses AutoResetEvent WaitOne with timeout which ensures non-reentry.

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.

How to know that a thread in a Thread Pool hangs/freezes

I have queue of tasks for the ThreadPool, and each task has a tendency to froze locking up all the resources it is using. And these cant be released unless the service is restarted.
Is there a way in the ThreadPool to know that its thread is already frozen? I have an idea of using a time out, (though i still dont know how to write it), but i think its not safe because the length of time for processing is not uniform.
I don't want to be too presumptuous here, but a good dose of actually finding out what the problem is and fixing it is the best course with deadlocks.
Run a debug version of your service and wait until it deadlocks. It will stay deadlocked as this is a wonderful property of deadlocks.
Attach the Visual Studio debugger to the service.
"Break All".
Bring up your threads windows, and start spelunking...
Unless you have a sound architecture\design\reason to choose victims in the first place, don't do it - period. It's pretty much a recipe for disaster to arbitrarily bash threads over the head when they're in the middle of something.
(This is perhaps a bit lowlevel, but at least it is a simple solution. As I don't know C#'s API, this is a general solution for any language using thread-pools.)
Insert a watchdog task after each real task that updates a time value with the current time. If this value is larger than you max task run time (say 10 seconds), you know that something is stuck.
Instead of setting a time and polling it, you could continuously set and reset some timers 10 secs into the future. When it triggers, a task has hung.
The best way is probably to wrap each task in a "Watchdog" Task class that does this automatically. That way, upon completion, you'd clear the timer, and you could also set a per-task timeout, which might be useful.
You obviously need one time/timer object for each thread in the threadpool, but that's solvable via thread-local variables.
Note that this solution does not require you to modify your tasks' code. It only modifies the code putting tasks into the pool.
One way is to use a watchdog timer (a solution usually done in hardware but applicable to software as well).
Have each thread set a thread-specific value to 1 at least once every five seconds (for example).
Then your watchdog timer wakes every ten seconds (again, this is an example figure only) and checks to ensure that all the values are 1. If they're not 1, then a thread has locked up.
The watchdog timer then sets them all to 0 and goes back to sleep for the next cycle.
Providing your worker threads are written in such a way so that they will be able to set the values in a timely manner under non-frozen conditions, this scheme will work okay.
The first thread that locks up will not set its value to 1, and this will be detected by the watchdog timer on the next cycle.
However, a better solution is to find out why the threads are freezing in the first place and fix that.

After FileSystemWatcher fires - Thread Pool or Dedicated thread?

I am about to implement the archetypal FileSystemWatcher solution. I have a directory to monitor for file creations, and the task of sucking up created files and inserting the into a DB. Roughly this will involve reading and processing 6 or 7, 80 char text files that appear at a rate of 150mS in bursts that occur every couple of seconds, and rarely a 2MB binary file will also have to be processed. This will most likely be a 24/7 process.
From what I have read about the FileSystemWatcher object it is better to enqueue its events in one thread and then dequeue/process them in another thread. The quandary I have right now is what would be the better creation mechanism of the thread that does the processing. The choices I can see are:
Each time I get a FSW event I manually create a new thread (yeah I know .. stupid architecture, but I had to say it).
Throw the processing at the CLR thread pool whenever I get an FSW event
On start up, create a dedicated second thread for the processing and use a producer/consumer model to handle the work. The main thread enqueues the request and the second thread dequeues it and performs the work.
I am tending towards the third method as the preferred one as I know the work thread will always be required - and also probably more so because I have no feel for the thread pool.
If you know that the second thread will always be required, and you also know that you'll never need more than one worker thread, then option three is good enough.
The third option is the most logical.
In regards to FSW missing some file events, I implemented this:
1) FSW Object which fires on FileCreate
2) tmrFileCheck, ticks = 5000 (5 seconds)
- Calls tmrFileChec_Tick
When the FileCreate event occurs, if (tmrFileCheck.Enabled == false) then tmrFileCheck.Start()
This way, after 10 seconds tmrFileCheck_Tick fires which
a) tmrFileCheck.Stop()
b) CheckForStragglerFiles
Of tests I've run, this works effectively where there are a < 100 files created per minute.
A variant is to merely have a timer tick ever NN seconds and sweep the directory(ies) for straggler files.
Another variant is to hire me to press F5 to refresh the window and call you when there are straggler files; just a suggestion. :-P
Just be aware that FileSystemWatcher may miss events, there's no guarantee it will deliver all specific events that have transpired. Your design of keeping the work done by the thread receiving events to a minimum, should reduce the chances of that happening, but it is still a possibility, given the finite event buffer size (tops out at 64KB).
I would highly recommend developing a battery of torture tests if you decide to use FileSystemWatcher.
In our testing, we encountered issues with network locations, that changing the InternalBufferSize did not fix, yet when we encountered this scenario, we did not receive Error event notifications either.
Thus, we developed our own polling mechanism for doing so, using Directory.GetFiles, followed by comparing the state of the returned files with the previously polled state, ensuring we always had an accurate delta.
Of course, this comes at a substantial cost in performance, which may not be good enough for you.

Categories