bakershawnm
Programmer
I have been looking through here trying to find an answer but have been unsuccessful. Maybe I am just not looking for the right key words.
However here is my multi-threading problem. This program is running as a service.
I have a parent class:
Public Class MasterImportClass
Protected _fldrinfo As DirectoryInfo
Protected _srcfile As Object
Protected Model, BndlId, Eff As String
Public Event Finished(ByVal Bar As String, ByVal imprtd As Integer)
Public Event StatusEvnt(ByVal who As String, ByVal imprtd As Integer)
Public Event ErrEvnt(ByVal errorinfo As String)
Public Event HoldMRE(ByVal who As String)
Public Event ReleaseMRE(ByVal who As String)
Private Mytimer As System.Timers.Timer
Protected x As Integer
Protected Child_Class_Identifier As String
Protected infile As FileInfo
Public Sub New()
End Sub
Public Property Identifier() As String
Get
Return Child_Class_Identifier
End Get
Set(ByVal value As String)
Child_Class_Identifier = value
End Set
End Property
Public Property fldrinfo() As DirectoryInfo
Get
Return _fldrinfo
End Get
Set(ByVal value As DirectoryInfo)
_fldrinfo = value
End Set
End Property
Public Property srcfile() As Object
Get
Return _srcfile
End Get
Set(ByVal value As Object)
_srcfile = value
End Set
End Property
Private Sub OnTimedEvent(ByVal source As Object, ByVal e As Timers.ElapsedEventArgs)
RaiseEvent StatusEvnt(Child_Class_Identifier, x)
End Sub
Protected Sub StartTimer()
Mytimer = New System.Timers.Timer(600000)
Mytimer.Enabled = True
AddHandler Mytimer.Elapsed, AddressOf OnTimedEvent
End Sub
Public Sub Init_Parser()
On Error GoTo Err_Parser
StartTimer()
RaiseEvent HoldMRE(Child_Class_Identifier)
x = 0
Parse()
Exit_Parser:
RaiseEvent ReleaseMRE(Child_Class_Identifier)
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
I have multiple children that I create based on this parent:
Public Class CL_SILS
Inherits MasterImportClass
Shadows Event Finished(ByVal lbl As String, ByVal imprtd As Integer)
Shadows Event StatusEvnt(ByVal lbl As String, ByVal imprtd As Integer)
Shadows Event ErrEvnt(ByVal errorinfo As String)
Public Sub New(ByVal ID As String)
Me.Child_Class_Identifier = ID
End Sub
Protected Overrides Sub Parse()
<parse data based on class. this is where the unique stuff happens.>
.
.
End Sub
End Class
Here is the Serivce base that uses the classes:
Public Class DataService
Inherits System.ServiceProcess.ServiceBase
Structure MREtype
Dim who As String
Dim mre As ManualResetEvent
End Structure
Private Shared MasterMRE As New ManualResetEvent(False)
Private Shared mres As New ArrayList()
Private Shared mre As New ManualResetEvent(False)
Dim thrdSvcCntrl As System.Threading.Thread
Dim thrdMWPrsr As System.Threading.Thread
Dim thrdCPrsr As System.Threading.Thread
Dim thrdBTPrsr As System.Threading.Thread
Dim thrdMWTPrsr As System.Threading.Thread
Dim thrdFOPrsr As System.Threading.Thread
Dim thrdSILSPrsr As System.Threading.Thread
Dim thrdMkByPrsr As System.Threading.Thread
Dim thrdBAIPrsr As System.Threading.Thread
Dim WithEvents MWPrsr As New MWClass("MWS")
Dim WithEvents CPrsr As New CL_Coder("CDR")
Dim WithEvents BTPrsr As New CL_BatTag("BtTg")
Dim WithEvents MWTPrsr As New CL_MWTape("MWT")
Dim WithEvents FOPrsr As New CL_FiringOrder("FO")
Dim WithEvents SILSPrsr As New CL_SILS("SILS")
Dim WithEvents MkByPrsr As New CL_MakeBuy("MkBy")
Dim WithEvents BAIPrsr As New CL_BAI("BAI")
Private srcfldr As String
Private mws, cdr, bttg, frodr, sils, mkby, mwt, bai As Integer
Private evntlog As New EventLog()
Dim Mytimer As System.Timers.Timer
Protected Overrides Sub OnStart(ByVal args() As String)
thrdSvcCntrl = New System.Threading.Thread(AddressOf Svc_Control)
thrdSvcCntrl.Start()
Mytimer = New System.Timers.Timer(3600000)
Mytimer.Enabled = True
AddHandler Mytimer.Elapsed, AddressOf OnTimedEvent
End Sub
Protected Overrides Sub OnStop()
Dim mre As MREtype
MasterMRE.WaitOne()
For Each mre In mres
mre.mre.WaitOne()
Next
Mytimer.Enabled = False
End Sub
Private Sub OnTimedEvent(ByVal source As Object, ByVal e As ElapsedEventArgs)
thrdSvcCntrl = New System.Threading.Thread(AddressOf Svc_Control)
thrdSvcCntrl.Start()
End Sub
Public Sub Svc_Control()
MasterMRE.Reset()
<More code . . .>
.
.
.
Exit_SvcCntrl:
MasterMRE.Set()
End Sub
Private Function Check_for_files() As Integer
<do stuff . . .>
End Function
Private Sub spawn_processes()
<spawn processes based on flags>
End Sub
Private Sub StatusEvntHndlr(ByVal lbl As String, ByVal imprtd As Integer) _
Handles MWPrsr.StatusEvnt, FOPrsr.StatusEvnt, CPrsr.StatusEvnt, BTPrsr.StatusEvnt, _
MWTPrsr.StatusEvnt, SILSPrsr.StatusEvnt, MkByPrsr.StatusEvnt, BAIPrsr.StatusEvnt
evntlog.WriteEntry(lbl & " has imported/update " & imprtd & " records.")
End Sub
Public Sub FnshEvntHndlrMthd(ByVal lbl As String, ByVal imprtd As Integer) _
Handles MWPrsr.Finished, FOPrsr.Finished, CPrsr.Finished, BTPrsr.Finished, _
MWTPrsr.Finished, SILSPrsr.Finished, MkByPrsr.Finished, BAIPrsr.Finished
evntlog.WriteEntry(lbl & " Finished. " & imprtd & " Records Imported. - " & Now())
End Sub
Public Sub ErrEvntHndlrMthd(ByVal errtxt As String) _
Handles MWPrsr.ErrEvnt, FOPrsr.ErrEvnt, SILSPrsr.ErrEvnt, MkByPrsr.ErrEvnt, _
BAIPrsr.ErrEvnt, BTPrsr.ErrEvnt, MWTPrsr.ErrEvnt
evntlog.WriteEntry(errtxt)
End Sub
Public Sub HoldMREHndlr(ByVal who As String) _
Handles MWPrsr.HoldMRE, FOPrsr.HoldMRE, SILSPrsr.HoldMRE, MkByPrsr.HoldMRE, _
BAIPrsr.HoldMRE, BTPrsr.HoldMRE, MWTPrsr.HoldMRE
Dim newmre As MREtype
evntlog.WriteEntry("Holding MRE for " & who)
newmre.who = who
newmre.mre = New ManualResetEvent(False)
newmre.mre.Reset()
mres.Add(newmre)
End Sub
Public Sub ReleaseMREHndlr(ByVal who As String) _
Handles MWPrsr.HoldMRE, FOPrsr.ReleaseMRE, SILSPrsr.ReleaseMRE, MkByPrsr.ReleaseMRE, _
BAIPrsr.ReleaseMRE, BTPrsr.ReleaseMRE, MWTPrsr.ReleaseMRE
Dim remmre As MREtype
evntlog.WriteEntry("Releasing MRE for " & who)
For Each remmre In mres
If remmre.who = who Then
remmre.mre.Set()
mres.Remove(remmre)
End If
Next
End Sub
End Class
The problem is that the HoldMRE and ReleaseMRE events for the spawned threads never get triggered. I never get an entry in my event log for hold or release. And when I stop the service while any of the spawned threads are running it does not hold until they finish like it is supposed to.
The HoldMRE supposed to be triggered by the Init_Prsr to keep the service from being shut down while any spawned processes are still running. And the ReleaseMRE releases that hold when the spawned process finishes.
I assumed the Init_Prsr would do everything the same in each child since it is defined in the parent and never redefined/overridden.
So where am I wrong and what should I be doing to so that it works.
However here is my multi-threading problem. This program is running as a service.
I have a parent class:
Public Class MasterImportClass
Protected _fldrinfo As DirectoryInfo
Protected _srcfile As Object
Protected Model, BndlId, Eff As String
Public Event Finished(ByVal Bar As String, ByVal imprtd As Integer)
Public Event StatusEvnt(ByVal who As String, ByVal imprtd As Integer)
Public Event ErrEvnt(ByVal errorinfo As String)
Public Event HoldMRE(ByVal who As String)
Public Event ReleaseMRE(ByVal who As String)
Private Mytimer As System.Timers.Timer
Protected x As Integer
Protected Child_Class_Identifier As String
Protected infile As FileInfo
Public Sub New()
End Sub
Public Property Identifier() As String
Get
Return Child_Class_Identifier
End Get
Set(ByVal value As String)
Child_Class_Identifier = value
End Set
End Property
Public Property fldrinfo() As DirectoryInfo
Get
Return _fldrinfo
End Get
Set(ByVal value As DirectoryInfo)
_fldrinfo = value
End Set
End Property
Public Property srcfile() As Object
Get
Return _srcfile
End Get
Set(ByVal value As Object)
_srcfile = value
End Set
End Property
Private Sub OnTimedEvent(ByVal source As Object, ByVal e As Timers.ElapsedEventArgs)
RaiseEvent StatusEvnt(Child_Class_Identifier, x)
End Sub
Protected Sub StartTimer()
Mytimer = New System.Timers.Timer(600000)
Mytimer.Enabled = True
AddHandler Mytimer.Elapsed, AddressOf OnTimedEvent
End Sub
Public Sub Init_Parser()
On Error GoTo Err_Parser
StartTimer()
RaiseEvent HoldMRE(Child_Class_Identifier)
x = 0
Parse()
Exit_Parser:
RaiseEvent ReleaseMRE(Child_Class_Identifier)
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
I have multiple children that I create based on this parent:
Public Class CL_SILS
Inherits MasterImportClass
Shadows Event Finished(ByVal lbl As String, ByVal imprtd As Integer)
Shadows Event StatusEvnt(ByVal lbl As String, ByVal imprtd As Integer)
Shadows Event ErrEvnt(ByVal errorinfo As String)
Public Sub New(ByVal ID As String)
Me.Child_Class_Identifier = ID
End Sub
Protected Overrides Sub Parse()
<parse data based on class. this is where the unique stuff happens.>
.
.
End Sub
End Class
Here is the Serivce base that uses the classes:
Public Class DataService
Inherits System.ServiceProcess.ServiceBase
Structure MREtype
Dim who As String
Dim mre As ManualResetEvent
End Structure
Private Shared MasterMRE As New ManualResetEvent(False)
Private Shared mres As New ArrayList()
Private Shared mre As New ManualResetEvent(False)
Dim thrdSvcCntrl As System.Threading.Thread
Dim thrdMWPrsr As System.Threading.Thread
Dim thrdCPrsr As System.Threading.Thread
Dim thrdBTPrsr As System.Threading.Thread
Dim thrdMWTPrsr As System.Threading.Thread
Dim thrdFOPrsr As System.Threading.Thread
Dim thrdSILSPrsr As System.Threading.Thread
Dim thrdMkByPrsr As System.Threading.Thread
Dim thrdBAIPrsr As System.Threading.Thread
Dim WithEvents MWPrsr As New MWClass("MWS")
Dim WithEvents CPrsr As New CL_Coder("CDR")
Dim WithEvents BTPrsr As New CL_BatTag("BtTg")
Dim WithEvents MWTPrsr As New CL_MWTape("MWT")
Dim WithEvents FOPrsr As New CL_FiringOrder("FO")
Dim WithEvents SILSPrsr As New CL_SILS("SILS")
Dim WithEvents MkByPrsr As New CL_MakeBuy("MkBy")
Dim WithEvents BAIPrsr As New CL_BAI("BAI")
Private srcfldr As String
Private mws, cdr, bttg, frodr, sils, mkby, mwt, bai As Integer
Private evntlog As New EventLog()
Dim Mytimer As System.Timers.Timer
Protected Overrides Sub OnStart(ByVal args() As String)
thrdSvcCntrl = New System.Threading.Thread(AddressOf Svc_Control)
thrdSvcCntrl.Start()
Mytimer = New System.Timers.Timer(3600000)
Mytimer.Enabled = True
AddHandler Mytimer.Elapsed, AddressOf OnTimedEvent
End Sub
Protected Overrides Sub OnStop()
Dim mre As MREtype
MasterMRE.WaitOne()
For Each mre In mres
mre.mre.WaitOne()
Next
Mytimer.Enabled = False
End Sub
Private Sub OnTimedEvent(ByVal source As Object, ByVal e As ElapsedEventArgs)
thrdSvcCntrl = New System.Threading.Thread(AddressOf Svc_Control)
thrdSvcCntrl.Start()
End Sub
Public Sub Svc_Control()
MasterMRE.Reset()
<More code . . .>
.
.
.
Exit_SvcCntrl:
MasterMRE.Set()
End Sub
Private Function Check_for_files() As Integer
<do stuff . . .>
End Function
Private Sub spawn_processes()
<spawn processes based on flags>
End Sub
Private Sub StatusEvntHndlr(ByVal lbl As String, ByVal imprtd As Integer) _
Handles MWPrsr.StatusEvnt, FOPrsr.StatusEvnt, CPrsr.StatusEvnt, BTPrsr.StatusEvnt, _
MWTPrsr.StatusEvnt, SILSPrsr.StatusEvnt, MkByPrsr.StatusEvnt, BAIPrsr.StatusEvnt
evntlog.WriteEntry(lbl & " has imported/update " & imprtd & " records.")
End Sub
Public Sub FnshEvntHndlrMthd(ByVal lbl As String, ByVal imprtd As Integer) _
Handles MWPrsr.Finished, FOPrsr.Finished, CPrsr.Finished, BTPrsr.Finished, _
MWTPrsr.Finished, SILSPrsr.Finished, MkByPrsr.Finished, BAIPrsr.Finished
evntlog.WriteEntry(lbl & " Finished. " & imprtd & " Records Imported. - " & Now())
End Sub
Public Sub ErrEvntHndlrMthd(ByVal errtxt As String) _
Handles MWPrsr.ErrEvnt, FOPrsr.ErrEvnt, SILSPrsr.ErrEvnt, MkByPrsr.ErrEvnt, _
BAIPrsr.ErrEvnt, BTPrsr.ErrEvnt, MWTPrsr.ErrEvnt
evntlog.WriteEntry(errtxt)
End Sub
Public Sub HoldMREHndlr(ByVal who As String) _
Handles MWPrsr.HoldMRE, FOPrsr.HoldMRE, SILSPrsr.HoldMRE, MkByPrsr.HoldMRE, _
BAIPrsr.HoldMRE, BTPrsr.HoldMRE, MWTPrsr.HoldMRE
Dim newmre As MREtype
evntlog.WriteEntry("Holding MRE for " & who)
newmre.who = who
newmre.mre = New ManualResetEvent(False)
newmre.mre.Reset()
mres.Add(newmre)
End Sub
Public Sub ReleaseMREHndlr(ByVal who As String) _
Handles MWPrsr.HoldMRE, FOPrsr.ReleaseMRE, SILSPrsr.ReleaseMRE, MkByPrsr.ReleaseMRE, _
BAIPrsr.ReleaseMRE, BTPrsr.ReleaseMRE, MWTPrsr.ReleaseMRE
Dim remmre As MREtype
evntlog.WriteEntry("Releasing MRE for " & who)
For Each remmre In mres
If remmre.who = who Then
remmre.mre.Set()
mres.Remove(remmre)
End If
Next
End Sub
End Class
The problem is that the HoldMRE and ReleaseMRE events for the spawned threads never get triggered. I never get an entry in my event log for hold or release. And when I stop the service while any of the spawned threads are running it does not hold until they finish like it is supposed to.
The HoldMRE supposed to be triggered by the Init_Prsr to keep the service from being shut down while any spawned processes are still running. And the ReleaseMRE releases that hold when the spawned process finishes.
I assumed the Init_Prsr would do everything the same in each child since it is defined in the parent and never redefined/overridden.
So where am I wrong and what should I be doing to so that it works.