bakershawnm
Programmer
I have been working on a service for a few weeks that will sit and monitor a specific daily folder. When it detects certain files it reacts by spawning threads to handle parsing the data into a database. Just to get the basics out of the way, I am using Visual Studio 2008 and VB.NET to SQL Server 2005.
Everything in my service works as it should except for one small problem. In my service controller (that is spawned by the hourly timer set up in the OnStart event) I reset a ManualResetEvent so that I can hold the controller and not allow the service to be stopped unless all threads are stopped (code below).
Private Shared waitHandles() As WaitHandle = _
{New AutoResetEvent(False), _
New AutoResetEvent(False), _
New AutoResetEvent(False), _
New AutoResetEvent(False), _
New AutoResetEvent(False), _
New AutoResetEvent(False), _
New AutoResetEvent(False), _
New AutoResetEvent(False), _
New AutoResetEvent(False)}
Public Sub Svc_Control()
MasterMRE.Reset()
.
.
.
evntlog.WriteEntry("Checking for files in " & srcfldr & ". - " & Now())
If Check_for_files() = True Then
spawn_processes()
evntlog.WriteEntry("All WaitHandles released")
Else
evntlog.WriteEntry("No Files to Import. - " & Now())
End If
MasterMRE.Set()
end sub
Then when I spawn the sub threads (from a sub proc within the main thread) with the waithandles I hold the that proc until all of the spawned sub threads have responded back with a ARE.set():
Private Sub spawn_processes()
If mws = True Then
evntlog.WriteEntry("Spawing Import for Sub Thread 1. - " & Now())
ThreadPool.QueueUserWorkItem(AddressOf MWPrsr.Init_Parser, waitHandles(0))
End If
.
.
( up to 7 more threads can be spawned )
.
.
WaitHandle.WaitAll(waitHandles)
End Sub
The parent class of the spawned threads looks like this:
Imports System.Threading
Public Class MasterImportClass
.
.
(class specific setup stuff)
.
.
Public Sub Init_Parser(ByVal state As [Object])
On Error GoTo Err_Parser
Dim are As AutoResetEvent = CType(state, AutoResetEvent)
x = 0
Parse()
Exit_Parser:
' RaiseEvent ReleaseMRE(Child_Class_Identifier)
are.Set()
Exit Sub
Err_Parser:
RaiseEvent ErrEvnt(Child_Class_Identifier & " *** " & Err.Number & " - " & Err.Description & vbLf & _
"File " & infile.Name & " Record Number " & x)
Resume Exit_Parser
End Sub
Protected Overridable Sub Parse()
End Sub
End Class
The overridable Parse() is where I do the file specific parsing for each different file type in each of the children classes.
So the problem is I never get the "All WaitHandles released" event in the event log even after all the sub threads finish (I know they finish because I get an event log entry telling me when each one finishes). This leads me to believe the are.set is never being reached or not being picked up by the controller thread. Is this possibly because I am doing the waitall in the sub proc and I should eliminate that and pull it up to the controller?
Any help will be much appreciated.
Thanks
shawn
Everything in my service works as it should except for one small problem. In my service controller (that is spawned by the hourly timer set up in the OnStart event) I reset a ManualResetEvent so that I can hold the controller and not allow the service to be stopped unless all threads are stopped (code below).
Private Shared waitHandles() As WaitHandle = _
{New AutoResetEvent(False), _
New AutoResetEvent(False), _
New AutoResetEvent(False), _
New AutoResetEvent(False), _
New AutoResetEvent(False), _
New AutoResetEvent(False), _
New AutoResetEvent(False), _
New AutoResetEvent(False), _
New AutoResetEvent(False)}
Public Sub Svc_Control()
MasterMRE.Reset()
.
.
.
evntlog.WriteEntry("Checking for files in " & srcfldr & ". - " & Now())
If Check_for_files() = True Then
spawn_processes()
evntlog.WriteEntry("All WaitHandles released")
Else
evntlog.WriteEntry("No Files to Import. - " & Now())
End If
MasterMRE.Set()
end sub
Then when I spawn the sub threads (from a sub proc within the main thread) with the waithandles I hold the that proc until all of the spawned sub threads have responded back with a ARE.set():
Private Sub spawn_processes()
If mws = True Then
evntlog.WriteEntry("Spawing Import for Sub Thread 1. - " & Now())
ThreadPool.QueueUserWorkItem(AddressOf MWPrsr.Init_Parser, waitHandles(0))
End If
.
.
( up to 7 more threads can be spawned )
.
.
WaitHandle.WaitAll(waitHandles)
End Sub
The parent class of the spawned threads looks like this:
Imports System.Threading
Public Class MasterImportClass
.
.
(class specific setup stuff)
.
.
Public Sub Init_Parser(ByVal state As [Object])
On Error GoTo Err_Parser
Dim are As AutoResetEvent = CType(state, AutoResetEvent)
x = 0
Parse()
Exit_Parser:
' RaiseEvent ReleaseMRE(Child_Class_Identifier)
are.Set()
Exit Sub
Err_Parser:
RaiseEvent ErrEvnt(Child_Class_Identifier & " *** " & Err.Number & " - " & Err.Description & vbLf & _
"File " & infile.Name & " Record Number " & x)
Resume Exit_Parser
End Sub
Protected Overridable Sub Parse()
End Sub
End Class
The overridable Parse() is where I do the file specific parsing for each different file type in each of the children classes.
So the problem is I never get the "All WaitHandles released" event in the event log even after all the sub threads finish (I know they finish because I get an event log entry telling me when each one finishes). This leads me to believe the are.set is never being reached or not being picked up by the controller thread. Is this possibly because I am doing the waitall in the sub proc and I should eliminate that and pull it up to the controller?
Any help will be much appreciated.
Thanks
shawn