tags:

views:

56

answers:

4

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();
    }
}
A: 

Sounds like maybe it's not really the same timer, and so the resources being "leaked" here are GDI handles.

Joel Coehoorn
...easily checked through Task Manager as well.
Will A
+3  A: 

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.

Sam
Is there a way to increase the threadpool?
Nathan
Is that a question? Why not post a question as a question instead of a comment :)
Timwi
@Nathan, Timwi is right, if you have another question the best thing to do is research it or ask a separate question. Makes it easier to get the right answer and for others to find the answer when they have the same question.
Sam
@Nathan, even though I believe extra questions should be asked separately, I edited my answer with more info.
Sam
A: 

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;
}
chilltemp
A: 

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

camilin87