System.Timers.Timer stops firing event

G

Guest

I have a Windows Service with a Timer object with an interval of 500 ms, in
each event the windows service starts a new thread, up to a limited number of
threads, and does some work.

It works fine as to the users requirements, but sometimes freezes. The
Service is running, its process is visible on Task Manager as usually, no
events on the Event Log are related to the service, but the work is not done.

After some tests I foun out that the the code associated with the OnTimer
Event stops being executed with no apparent reason.

I'm clueless.... :(

Some code:


public class QueueHandler : System.ServiceProcess.ServiceBase
{
private System.ComponentModel.Container components = null;
private System.Timers.Timer timer = new System.Timers.Timer();
private Thread[] serviceThreads;

protected override void OnStart(string[] args)
{
serviceThreads = new Thread[25];
int interval = 500;
string autoThreads = "no";

timer.Elapsed += new ElapsedEventHandler(OnTimer);
timer.Interval = interval;
timer.Enabled = true;
}

protected void OnTimer(Object Source,ElapsedEventArgs e)
{
int x = GetNextFreeThread();

if (x >= 0)
serviceThreads[x].Start();
}

private int GetNextFreeThread()
{
int threadID = -1;

MessageProcessor mProcessor = new MessageProcessor();
ThreadStart tStart = new ThreadStart(mProcessor.ProcessMessage);

for (int y = 0;y<serviceThreads.Length;y++)
{
//if thread slot is free instaciate new thread
if(serviceThreads[y] == null || serviceThreads[y].ThreadState ==
System.Threading.ThreadState.Stopped)
{
threadID = y;
serviceThreads[threadID] = new Thread(tStart);
serviceThreads[threadID].Name = "QueueThread_" + y.ToString();
serviceThreads[threadID].IsBackground = true;
serviceThreads[threadID].Priority = ThreadPriority.Lowest;
break;
}
}

return threadID;
}
 
S

sloan

I prefer to "code up" my timers.

I only have the vb.net version at the moment:



Private m_doTheWorkTimer As Timer



private sub RegisterTimer()

Dim dueTime As Long

Dim period As Long

' DUE TIME looks like it is the DELAY time .. from the time the service
starts,

' Until this specfic TIMER kicks in. So a Delay Time of 20000

' Will DELAY this timer shooting off until 20 seconds (20000 ms) after the
service starts

dueTime = 20000

period = 5000

' the magic bullet, notice the part after "AddressOf", which is the method

Dim timerHandler = New TimerCallback(AddressOf BeepClass.GoBeep)

m_doTheWorkTimer = New Timer(timerHandler , Me, dueTime, period)

end sub



Public Class BeepClass



Public Shared Sub GoBeep(ByVal state As Object)'' this uses a built in
delegate, with "state as Object" as the generic argument list

Beep()

End Sub



End Class


Outside of the wire up event handler, the C# conversion is easy.

HEre is C# code also:

http://msdn2.microsoft.com/en-us/library/system.threading.timercallback.aspx






Rui Pedro Sousa said:
I have a Windows Service with a Timer object with an interval of 500 ms, in
each event the windows service starts a new thread, up to a limited number of
threads, and does some work.

It works fine as to the users requirements, but sometimes freezes. The
Service is running, its process is visible on Task Manager as usually, no
events on the Event Log are related to the service, but the work is not done.

After some tests I foun out that the the code associated with the OnTimer
Event stops being executed with no apparent reason.

I'm clueless.... :(

Some code:


public class QueueHandler : System.ServiceProcess.ServiceBase
{
private System.ComponentModel.Container components = null;
private System.Timers.Timer timer = new System.Timers.Timer();
private Thread[] serviceThreads;

protected override void OnStart(string[] args)
{
serviceThreads = new Thread[25];
int interval = 500;
string autoThreads = "no";

timer.Elapsed += new ElapsedEventHandler(OnTimer);
timer.Interval = interval;
timer.Enabled = true;
}

protected void OnTimer(Object Source,ElapsedEventArgs e)
{
int x = GetNextFreeThread();

if (x >= 0)
serviceThreads[x].Start();
}

private int GetNextFreeThread()
{
int threadID = -1;

MessageProcessor mProcessor = new MessageProcessor();
ThreadStart tStart = new ThreadStart(mProcessor.ProcessMessage);

for (int y = 0;y<serviceThreads.Length;y++)
{
//if thread slot is free instaciate new thread
if(serviceThreads[y] == null || serviceThreads[y].ThreadState ==
System.Threading.ThreadState.Stopped)
{
threadID = y;
serviceThreads[threadID] = new Thread(tStart);
serviceThreads[threadID].Name = "QueueThread_" + y.ToString();
serviceThreads[threadID].IsBackground = true;
serviceThreads[threadID].Priority = ThreadPriority.Lowest;
break;
}
}

return threadID;
}
 
M

Morten Wennevik

Hi,

There are some articles on the net describing that you should never use
System.Timers.Timer in a windows service, although I have yet to find out
why. I have, however, personal experiences with System.Timers.Timer not
working in a windows service.

The solution for this is to use System.Threading.Timer
 
G

Guest

Hi Bryan,

Thanks for your reply.

The MessageProcessor Class reads a MSMQ Queue, which can be a great part of
the problem because there is some unmanaged code behind System.Messaging.

It also writes stuff to SQL using the Data Application Block.

I'll post some code.

Bryan Phillips said:
What classes are you using in the ProcessMessage method? I had problems
with hanging a windows service while I tried using the PrintDocument
class.

Bryan Phillips
MCSD, MCDBA, MCSE
Blog: http://bphillips76.spaces.live.com




I have a Windows Service with a Timer object with an interval of 500 ms, in
each event the windows service starts a new thread, up to a limited number of
threads, and does some work.

It works fine as to the users requirements, but sometimes freezes. The
Service is running, its process is visible on Task Manager as usually, no
events on the Event Log are related to the service, but the work is not done.

After some tests I foun out that the the code associated with the OnTimer
Event stops being executed with no apparent reason.

I'm clueless.... :(

Some code:


public class QueueHandler : System.ServiceProcess.ServiceBase
{
private System.ComponentModel.Container components = null;
private System.Timers.Timer timer = new System.Timers.Timer();
private Thread[] serviceThreads;

protected override void OnStart(string[] args)
{
serviceThreads = new Thread[25];
int interval = 500;
string autoThreads = "no";

timer.Elapsed += new ElapsedEventHandler(OnTimer);
timer.Interval = interval;
timer.Enabled = true;
}

protected void OnTimer(Object Source,ElapsedEventArgs e)
{
int x = GetNextFreeThread();

if (x >= 0)
serviceThreads[x].Start();
}

private int GetNextFreeThread()
{
int threadID = -1;

MessageProcessor mProcessor = new MessageProcessor();
ThreadStart tStart = new ThreadStart(mProcessor.ProcessMessage);

for (int y = 0;y<serviceThreads.Length;y++)
{
//if thread slot is free instaciate new thread
if(serviceThreads[y] == null || serviceThreads[y].ThreadState ==
System.Threading.ThreadState.Stopped)
{
threadID = y;
serviceThreads[threadID] = new Thread(tStart);
serviceThreads[threadID].Name = "QueueThread_" + y.ToString();
serviceThreads[threadID].IsBackground = true;
serviceThreads[threadID].Priority = ThreadPriority.Lowest;
break;
}
}

return threadID;
}
 
G

Guest

Hi sloan,

Your code is using the System.Threading.Timer class instead of the
System.Timers.Timer class I was using.

That was problem with my code, I was using the wrong class, as it is
explained in this article: http://support.microsoft.com/kb/842793

Thanks. ;)

sloan said:
I prefer to "code up" my timers.

I only have the vb.net version at the moment:



Private m_doTheWorkTimer As Timer



private sub RegisterTimer()

Dim dueTime As Long

Dim period As Long

' DUE TIME looks like it is the DELAY time .. from the time the service
starts,

' Until this specfic TIMER kicks in. So a Delay Time of 20000

' Will DELAY this timer shooting off until 20 seconds (20000 ms) after the
service starts

dueTime = 20000

period = 5000

' the magic bullet, notice the part after "AddressOf", which is the method

Dim timerHandler = New TimerCallback(AddressOf BeepClass.GoBeep)

m_doTheWorkTimer = New Timer(timerHandler , Me, dueTime, period)

end sub



Public Class BeepClass



Public Shared Sub GoBeep(ByVal state As Object)'' this uses a built in
delegate, with "state as Object" as the generic argument list

Beep()

End Sub



End Class


Outside of the wire up event handler, the C# conversion is easy.

HEre is C# code also:

http://msdn2.microsoft.com/en-us/library/system.threading.timercallback.aspx






Rui Pedro Sousa said:
I have a Windows Service with a Timer object with an interval of 500 ms, in
each event the windows service starts a new thread, up to a limited number of
threads, and does some work.

It works fine as to the users requirements, but sometimes freezes. The
Service is running, its process is visible on Task Manager as usually, no
events on the Event Log are related to the service, but the work is not done.

After some tests I foun out that the the code associated with the OnTimer
Event stops being executed with no apparent reason.

I'm clueless.... :(

Some code:


public class QueueHandler : System.ServiceProcess.ServiceBase
{
private System.ComponentModel.Container components = null;
private System.Timers.Timer timer = new System.Timers.Timer();
private Thread[] serviceThreads;

protected override void OnStart(string[] args)
{
serviceThreads = new Thread[25];
int interval = 500;
string autoThreads = "no";

timer.Elapsed += new ElapsedEventHandler(OnTimer);
timer.Interval = interval;
timer.Enabled = true;
}

protected void OnTimer(Object Source,ElapsedEventArgs e)
{
int x = GetNextFreeThread();

if (x >= 0)
serviceThreads[x].Start();
}

private int GetNextFreeThread()
{
int threadID = -1;

MessageProcessor mProcessor = new MessageProcessor();
ThreadStart tStart = new ThreadStart(mProcessor.ProcessMessage);

for (int y = 0;y<serviceThreads.Length;y++)
{
//if thread slot is free instaciate new thread
if(serviceThreads[y] == null || serviceThreads[y].ThreadState ==
System.Threading.ThreadState.Stopped)
{
threadID = y;
serviceThreads[threadID] = new Thread(tStart);
serviceThreads[threadID].Name = "QueueThread_" + y.ToString();
serviceThreads[threadID].IsBackground = true;
serviceThreads[threadID].Priority = ThreadPriority.Lowest;
break;
}
}

return threadID;
}
 
S

sloan

Yeah,

I didn't like those "Drag and Drop" timers way back in VB4,VB5 or VB6.

Something told me to avoid them ..... when I was writing a Windows Service.

But thanks for the concrete reason at the KB.

You ought to email this shoney:
http://www.codeguru.com/columns/dotnet/article.php/c6919/
and let him know.





Rui Pedro Sousa said:
Hi sloan,

Your code is using the System.Threading.Timer class instead of the
System.Timers.Timer class I was using.

That was problem with my code, I was using the wrong class, as it is
explained in this article: http://support.microsoft.com/kb/842793

Thanks. ;)

sloan said:
I prefer to "code up" my timers.

I only have the vb.net version at the moment:



Private m_doTheWorkTimer As Timer



private sub RegisterTimer()

Dim dueTime As Long

Dim period As Long

' DUE TIME looks like it is the DELAY time .. from the time the service
starts,

' Until this specfic TIMER kicks in. So a Delay Time of 20000

' Will DELAY this timer shooting off until 20 seconds (20000 ms) after the
service starts

dueTime = 20000

period = 5000

' the magic bullet, notice the part after "AddressOf", which is the method

Dim timerHandler = New TimerCallback(AddressOf BeepClass.GoBeep)

m_doTheWorkTimer = New Timer(timerHandler , Me, dueTime, period)

end sub



Public Class BeepClass



Public Shared Sub GoBeep(ByVal state As Object)'' this uses a built in
delegate, with "state as Object" as the generic argument list

Beep()

End Sub



End Class


Outside of the wire up event handler, the C# conversion is easy.

HEre is C# code also:

http://msdn2.microsoft.com/en-us/library/system.threading.timercallback.aspx






Rui Pedro Sousa said:
I have a Windows Service with a Timer object with an interval of 500
ms,
in
each event the windows service starts a new thread, up to a limited
number
of
threads, and does some work.

It works fine as to the users requirements, but sometimes freezes. The
Service is running, its process is visible on Task Manager as usually, no
events on the Event Log are related to the service, but the work is
not
done.
After some tests I foun out that the the code associated with the OnTimer
Event stops being executed with no apparent reason.

I'm clueless.... :(

Some code:


public class QueueHandler : System.ServiceProcess.ServiceBase
{
private System.ComponentModel.Container components = null;
private System.Timers.Timer timer = new System.Timers.Timer();
private Thread[] serviceThreads;

protected override void OnStart(string[] args)
{
serviceThreads = new Thread[25];
int interval = 500;
string autoThreads = "no";

timer.Elapsed += new ElapsedEventHandler(OnTimer);
timer.Interval = interval;
timer.Enabled = true;
}

protected void OnTimer(Object Source,ElapsedEventArgs e)
{
int x = GetNextFreeThread();

if (x >= 0)
serviceThreads[x].Start();
}

private int GetNextFreeThread()
{
int threadID = -1;

MessageProcessor mProcessor = new MessageProcessor();
ThreadStart tStart = new ThreadStart(mProcessor.ProcessMessage);

for (int y = 0;y<serviceThreads.Length;y++)
{
//if thread slot is free instaciate new thread
if(serviceThreads[y] == null || serviceThreads[y].ThreadState ==
System.Threading.ThreadState.Stopped)
{
threadID = y;
serviceThreads[threadID] = new Thread(tStart);
serviceThreads[threadID].Name = "QueueThread_" + y.ToString();
serviceThreads[threadID].IsBackground = true;
serviceThreads[threadID].Priority = ThreadPriority.Lowest;
break;
}
}

return threadID;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top