I have the following piece of code, that runs a "select" on certain table that needs to be monitored every 200 miliseconds
timerMonitoreoOrdenes = new System.Timers.Timer(FRECUENCIA_MONITOREO_ORDENES);
timerMonitoreoOrdenes.Elapsed += new ElapsedEventHandler(timerMonitoreoOrdenes_Elapsed);
timerMonitoreoOrdenes.Enabled = true;
timerMonitoreoOrdenes.AutoReset = true;
In the timerMonitoreoOrdenes_Elapsed
method I run a stored procedure that returns a DataSet
and for each row I am creating a new Object that is stored in memory Queue
The program is designed to be running all the time (like a windows service) but after the programs runs for a few hours I am getting this exception
System.OutOfMemoryException:
in System.Threading.ExecutionContext.CreateCopy()
in System.Threading._TimerCallback.PerformTimerCallback(Object state)
The reason that I am doing this like this is becase there is an external program that is inserting records on the DB with status=0 and I need to take those records, process them and set the status=1. There are some Thread that are taking records from the Queue
Is important to mention that This is for a REAL-TIME-TRADING application that 1 second delay in the information is too high
Sure, that is quite possible. A Timer that's ticking with AutoReset = true is a ticking time bomb. Things go drastically wrong if the Interval is too short. Using 200 msec is pretty risky, dbase update queries can easily take longer than that. Particularly so if the column you are looking for isn't indexed.
Your Elapsed event handler will run again even though the previous one isn't completed. On another thread-pool thread. Each thread will consume a megabyte of memory, plus whatever you need for the query and processing. This just continues, creating ever more threads. The thread-pool manager will make an effort to limit this but the maximum number of threads is allows to run is very high. High enough to cause arbitrary code to eventually fall over with OOM.
Use AutoReset = false and call Start() again at the end of your Elapsed event handler. And use a reasonable Interval that's at least close to the actual processing time. And add an index on that column so the dbase engine doesn't have to look at every record in the table.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With