Reputation: 182
I have a windows service doing 3 scheduled jobs. First of them is sending an email to employees their shift times. Second one is getting Active Directory information and saving it to local database. Last one is saving active directory photos to file directory.
Each job is done on a separate thread. Timer ticks every 45 seconds. Everything is running perfectly except the memory usage by the service which is increasing steadily.
Do you have any idea what might be causing this?
Thread[] thread;
protected override void OnStart(string[] args)
{
timer = new System.Timers.Timer();
timer.AutoReset = true;
timer.Enabled = true;
timer.Interval = 1000 * 45;
timer.Start();
timer.Elapsed += Timer_Elapsed;
servisList = new List<IService>() { new ShiftNotification(), new ActiveDirectoryService(), new DirectoryPhotos() };
thread = new Thread[servisList.Count];
}
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
try
{
for (int i = 0; i < servisList.Count; i++)
{
if (thread[i] == null)
{
if (TimeControl.CheckTime(DateTime.Now, servisList.ElementAt(i).sProps))
{
thread[i] = new System.Threading.Thread(new System.Threading.ThreadStart(servisList.ElementAt(i).NotifyUsers));
thread[i].Start();
}
}
else
{
if (thread[i].ThreadState != System.Threading.ThreadState.Running)
{
if (TimeControl.CheckTime(DateTime.Now, servisList.ElementAt(i).sProps))
{
thread[i] = new System.Threading.Thread(new System.Threading.ThreadStart(servisList.ElementAt(i).NotifyUsers));
thread[i].Start();
}
}
}
}
}
catch (Exception ex)
{
}
}
Upvotes: 4
Views: 3961
Reputation: 28355
Just a few ideas for this
ActiveDirectory
and SmcpClient
(correct me if you aren't using it for emails) usage means that you're dealing with unmanaged resources, are you disposing those classes correctly? You probably should make client variables as static fields and dispose them at the end of your program.These lines are unclear for me:
if (thread[i].ThreadState != System.Threading.ThreadState.Running)
{
if (TimeControl.CheckTime(DateTime.Now, servisList.ElementAt(i).sProps))
{
thread[i] = new System.Threading.Thread(new System.Threading.ThreadStart(servisList.ElementAt(i).NotifyUsers));
thread[i].Start();
}
}
Thread
is unmanaged resource too, so, as it's implementing the IDisposable
, you should dispose previous one before assigning the new value for the array entry: thread[i].Dispose();
minor Why do you use full names as you already added using System.Threading
?
Upvotes: 2
Reputation: 1086
AFAICT, it isn't possible to answer this without more specific information about what you are doing in that NotifyUsers method.
But even before looking into that, I would first revisit this thread-spawning logic you've got there, with this
if (thread[i] == null)
{
// (code omitted)
}
else
{
// (code omitted)
}
By that, I mean, first try to figure out whether or not your service ends up spawning too many of those worker threads, to begin with (which is my wild guess, a priori).
More specifically, as soon as / every time you're using System.Threading.Thread, always think of race condition as one of the first / most likely issues to be aware of.
Multi-threading is never easy. But plenty of resources are out there to help you get it done right.
'Hope this helps.
Upvotes: 0