c# new thread from timer handle issue - c#

Im experimenting with the following code
private void timer1_Tick(object sender, EventArgs e)
{
Thread nT = new Thread(new ThreadStart (checkThread));
nT.Start();
}
The cheackThread() function carries out a web-request and the timer's tick property is 2000ms. All objects in the checkThread() are disposed of after use. When the program is run for long periods e.g 3 hours the OS complains about low resources. I notices that in ctrl-alt-delete the handle count is increasing when the app runs. Does the thread not release its memory automatically once it has executed all its code or is this one of those times gc.collect is permitted?

the timer's tick property is 2ms
First, your timer will not honor this. The resolution is ~20 ms.
But even 20 ms is not very long for a Webrequest. If your checkThread exceeds 20ms (every now and then) then you would be starting Threads quicker than they can finish. And so they pile up. The fact that it takes a few hours makes me think this is the most likely cause.
You could use a debugger, or a simple counter activeThreads (use Interlocked) to diagnose this.
Using the ThreadPool or the TPL (Fx4) would solve some of your issues but you would still need to check and limit the number of simultaneous requests.

You should let the Framework handle the threads, instead of using Thread go for ThreadPool.QueueUserWorkItem

Related

When to use and what is the difference of a timer and thread?

Just now have some confusion about timer and thread, see below example, Both codes provide the same result (Do some checking every 60 seconds), so when should I use a timer and when should I use a thread to handle jobs when they're providing the same result?
Use Thread:
Thread checkJob = new Thread(checkStatus);
checkJob.Start();
protected void checkStatus()
{
//Do Checking here
Thread.Sleep(60000);
}
Use Timer:
public Form1()
{
InitializeComponent();
Timer time = new Timer();
time.Interval = 60000;
time.Tick += time_Tick;
time.Enabled = true;
}
void time_Tick(object sender, EventArgs e)
{
//Do Checking here
}
If the task that is performed periodically is very short, and will not get in the way of processing on the thread that the timer runs, then a timer is a reasonable choice.
On the other hand, if the periodic task takes a significant amount of time, and you cannot afford to have the main thread interrupted to perform it, then a separate dedicated thread is a good choice.
It depends on the timer you're using. If you're using a WinForms timer then your callback will fire on the gui thread. If you've got a lot of work to do then this will cause your application to block until you've finished, which will make for a bad user experience.
If you're using one of the other timers then they'll fire on a thread in the thread pool. Even here you'll want to avoid doing anything to long, but it won't block your gui thread. However, you're need to ensure you marshal any calls into the gui using the BeginInvoke method.
Starting your own thread is good if you're got long running tasks to do every time the timer fires, but once again you'll want to marshal calls back to the gui thread. Rather than using Thread.Sleep it's better to use an Event so that you can detect when the rest of the system is shutting down:
ManualResetEvent stopEvent = new ManualResetEvent(false);
Thread checkJob = new Thread(checkStatus);
checkJob.Start();
protected void checkStatus()
{
//Do Checking here
while(stopEvent.Wait(60000) == false)
{
// Do processing
}
}
Now you can stop the thread by calling stopEvent.Set()
You can view a thread as a "sub-process"; a process can have multiple threads, allowing it to perform several operations in parallel. A thread is an expensive system resource; it uses a CPU when it's active, and allocates its own call stack (1MB by default). Using a thread to perform periodic actions is a waste of precious resources, and doesn't scale well.
A timer, in the other hand, is much cheaper. It's just a time-controlled trigger that does nothing most of the time, except when it's time to execute your code. It's the right choice in your case.
I would recommend to use Timer - it is more suitable when it comes to resource consumption.
Setting up a new thread is quite expansive.
By the way in case you would like to use Thread you should set it to IsBackground=true, so that it can finish its execution when the application is shutdown.

overlooping in C#

I am going to create a system service in C#.
In the onstart section I would like to loop every 30 seconds and query a mysql database. If numrows are greater than 0 I will process some faxes using the faxcom library.
My question is: Would looping every 30 seconds exhaust the program/computer? What would be the best function/method to use for the loop and sleep? Do you have any example code for the loop and sleep?
Using Thread.Sleep() would be a bad solution, because even while sleeping your thread is active. Use Timer class instead and handle its Elapsed event.
This article examines different ways to tackle the periodical execution of your service.
Here is what your OnStart method might look like:
using System.Timers;
private timer = new Timer();
protected override void OnStart(string[] args)
{
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Interval = 30000; // every 30 seconds
timer.Enabled = true;
}
Private void OnElapsedTime(object source, ElapsedEventArgs e)
{
// Execute your code here
}
I wouldn't use looping constructs for such a thing.
I would use one of the timer controls in the BCL and set it to fire every 30 seconds.
As for the question of if this is "too much", the answer entirely depends on the amount of work being done and the load it generates.
No, you would not be using the CPU, because sleeping threads are not scheduled for execution until their sleep time expires. Use Thread.Sleep to make the current thread sleep for timeout miliseconds. Something like:
while(!stop) // boolean variable to indicate when to stop the service.
{
Thread.Sleep(30000);
// do work
}
You will, of course, need to run this on a separate thread, otherwise you will block the main thread.
I would avoid using System.Timers.Timer in your case solely because you are writing a Windows Service. While you can use it, you won't have a GUI available and therefore don't need anything that this timer would expose as if you were using a GUI (it inherits from System.ComponentModel.Component for this reason). It's pretty simple
to use.

Multi Thread c# application System.OutOfMemoryException after 1~5 minutes of runtime

Here is my Timer Elapsed Event, I am receiving the System.OutOfMemoryException on the line Thread thread = new Thread(threadStart);
I am receiving the error fairly fast (1~5 minutes, randomly), and it does not cause unexpected results in my program. I am just wondering what is causing this error, and I am afraid it may cause unexpected results if it is left unchecked. I have searched on the internet and am comming no where near the number of max threads.
readList contains about 46 enteries.
Any help would be appreciated.
private void glob_loopTimer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
ParameterizedThreadStart threadStart = new ParameterizedThreadStart(readHoldingRegisters);
foreach (readwriteDataGridRow.Read row in readList)
{
Thread thread = new Thread(threadStart);
thread.IsBackground = true;
thread.Start(System.Convert.ToInt32(row.Address));
}
}
catch (Exception ex)
{
UpdateConsole(new object[] { ex.Message.ToString() + " " + ex.StackTrace.ToString(), Color.Red });
Thread.CurrentThread.Abort(); // maybe?
}
}
EDIT:
Here is a bit more information.
My program is reading registers from a Serial Device using the Modbus RTU protocol.
A single register takes less than a tenth of a second to retrieve from readHoldingRegisters
I am open to suggestions on what else to use rather than threads.
note: I need to call readHoldingRegisters 40 - 100 times in a single 'pass'. The passes start when the user hits connect and end when he hits disconnect. Timers are not needed, they just offered a simple way for me to maintain the loop with a start and stop button.
EDIT: Solved
private void glob_loopTimer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
foreach (readwriteDataGridRow.Read row in readList)
{
readHoldingRegisters(row.Address);
}
}
catch (Exception ex)
{
UpdateConsole(new object[] { ex.Message.ToString() + " " + ex.StackTrace.ToString(), Color.Red });
}
}
The additional Threads were the problem and were not needed.
Ughh, do not, ever (well almost ever) abort threads. There are many preferable ways to make a System.Thread stop. Look around SO, you will find plenty of examples on why doing this is a bad idea and alternative approaches.
On with your question: The problem doesn't seem to be the number of rows in readList. It is more likely that your glob_looperTimer_Elapsed event handler is being executed many times and you are basically starting more and more threads.
What is the interval of your glob_loopTimer?
So how many times is glob_loopTimer_Elapsed called? The name implies that it is run on a periodic timer interval. If so, and if the 46 threads that get created on each invocation do not terminate about as quickly as the timer interval fires, then you could easily be spawning too many threads and running out of memory space as a result. Perhaps you could try logging when each thread starts and when each one finishes to get an idea about how many are in flight at once?
Keep in mind that every thread you allocate will have a certain amount of stack space allocated to it. Depending upon your runtime configuration, this amount of stack space may not be negligible (as in, it may be 1 MB per thread or more) and it may quickly consume your available memory even if you're not close to approaching the theoretical maximum number of threads supported by the OS.
Besides your problem I'll consider using ThreadPool or the TPL.
When using System.Thread there is no automisn to manage the threads...
Also each Thread allocates some memory which could lead to you problem.
The Threadpool and the TPL manage this resources by themselves
see also: -> Thread vs ThreadPool
Reusing threads that have already been created instead of creating new ones (an expensive process)
...
If you queue 100 thread pool tasks, it will only use as many threads as have already been created to service these requests (say 10
for example). The thread pool will make frequent checks (I believe
every 500ms in 3.5 SP1) and if there are queued tasks, it will make
one new thread. If your tasks are quick, then the number of new
threads will be small and reusing the 10 or so threads for the short
tasks will be faster than creating 100 threads up front.
If your workload consistently has large numbers of thread pool requests coming in, then the thread pool will tune itself to your
workload by creating more threads in the pool by the above process so
that there are a larger number of thread available to process requests
check Here for more in depth info on how the thread pool functions under the hood
I just know
Each thread also consumes (by default) around 1 MB of memory.

thread get 100% CPU very fast

I am implementing a very basic thread in C#:
private Thread listenThread;
public void startParser()
{
this.listenThread = new Thread(new ThreadStart(checkingData));
this.listenThread.IsBackground = true;
this.listenThread.Start();
}
private void checkingData()
{
while (true)
{
}
}
Then I immediately get 100% CPU. I want to check if sensor data is read inside the while(true) loop. Why it is like this?
Thanks in advance.
while (true) is what killing your CPU.
You can add Thread.Sleep(X) to you while to give CPU some rest before checking again.
Also, seems like you actually need a Timer.
Look at one of the Timer classes here http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx.
Use Timer with as high pulling interval as you can afford, 1 sec, half a sec.
You need to tradeoff between CPU usage and the maximum delay you can afford between checks.
Let your loop sleep. It's running around and around and getting tired. At the very least, let it take a break eventually.
Because your function isn't doing anything inside the while block, it grabs the CPU, and, for all practical purposes, never lets go of it, so other threads can do their work
private void checkingData()
{
while (true)
{
// executes, immediately
}
}
If you change it to the following, you should see more reasonable CPU consumption:
private void checkingData()
{
while (true)
{
// read your sensor data
Thread.Sleep(1000);
}
}
you can use blocking queue. take a item from blocking queue will block the thread until there is a item put into the queue. that doesn't cost any cpu.
with .net4, you can use BlockingCollection http://msdn.microsoft.com/en-us/library/dd267312.aspx
under version 4, there is not blocking queue int .net framework.
you can find many implements of blocking queue if you google it.
here is a implementation
http://www.codeproject.com/KB/recipes/boundedblockingqueue.aspx
by the way. where does the data you wait come from?
EDIT
if you want to check file. you can use FileSystemWatcher to check it with thread block.
if your data comes from external API and the api doesn't block the thread, there is no way to block the thread except use Thread.Sleep
If you're polling for a condition, definitely do as others suggested and put in a sleep. I'd also add that if you need maximum performance, you can use a statistical trick to avoid sleeping when sensor data has been read. When you detect sensor data is idle, say, 10 times in a row, then start to sleep on each iteration again.

Timer Delay Degrades or becomes inconsistent over time?

I'm hoping someone can shed some light on what might be happening for me. Here's a summary of whats happening.
I have an application that does lots of "stuff". Its a pretty hefty application that does lots of number crunching using many threads. There are several timers that are used. Over a long period of time, the timers stop consistently invoking the elapsed handler.
For instance: I have a timer set to elapse every second. After a period of hours the timer starts randomly triggering late. If I do not restart the application the performance just degrades and the timers fire later and later eventually turning into 3 or 4 seconds, forcing me to restart the application. I have not been able to identify any leaks. CPU usage does not go up, memory does not go up, and the server is no where near being maxed out. Can anyone give me some ideas as to what may be causing this?
private void Timer_Elapsed(object source, ElapsedEventArgs e)
{
if (seconds > 0)
{
seconds--;
timer.Start();
}
}
Is it possible you're exhausting the thread pool? Most timers invoke the handler using a threadpool thread. If all threadpool threads are in use, it will just get queued until one is available.
If that's the case switch some of your processing to use your own threads, not threadpool threads.
To test if you're exhausting the thread pool start up a background thread that periodically (a few times a second) checks ThreadPool.GetAvailableThreads and logs a message when the available is small (even if it's never actually zero when you check, if it sometimes approaches zero then it's likely this is the problem).
The size of the pool can be changed with ThreadPool.SetMaxThreads although that may not be the best solution. If you're using threadpool threads for longer running tasks, stop it. For long-running tasks use your own threads.
the timer class you use is really important
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx
but I don't think the problem is the timer itself,
for instance try making an application using the same timer class
that ONLY writes the current DateTime to a log file
and leave it running for an extremely long period of time, you'll see that there's no such a 3/4 seconds delay
review your timer code and check that no shared resources are being accessed at the same time,
maybe the Timer is OK, but there's a bottleneck in the event handler function or in "something" that function uses
Sounds like maybe it's not really the same timer, and so the resources being "leaked" here are GDI handles.
Possible workaround:
DateTime mayContinue = DateTime.MinValue;
bool blockingUi = false;
private void Timer_Elapsed(object source, ElapsedEventArgs e)
{
if( blockingUi )
{
if( DateTime.Now < mayContinue )
{
// Notify time remaining
// Update the UI with a BeginInvoke
}
else
{
blockingUi = false;
// Notify ready
// Update the UI with a BeginInvoke
}
}
}
private void BlockUi()
{
mayContinue = DateTime.Now.AddSeconds(30);
blockingUi = true;
}

Categories

Resources