AWestEng
asked on
RemoveHandler problem
Hi
Here I have some pseudocode that shows an example of my handler problem.
1: I have a process with an exit handler
2: In another methods I remove the handler and kill the process
Problem:
When killing the process the exit methods is still executing, so the removehandler dosen't seem to work. any tips here?
Thx
Here I have some pseudocode that shows an example of my handler problem.
1: I have a process with an exit handler
2: In another methods I remove the handler and kill the process
Problem:
When killing the process the exit methods is still executing, so the removehandler dosen't seem to work. any tips here?
Thx
Private Property LaunchedProcesses() As Hashtable
Get
Return m_serverProcess
End Get
Set(ByVal Value As Hashtable)
m_serverProcess = Value
End Set
End Property
Private Sub myProcess_Exited(ByVal sender As Object, ByVal e As System.EventArgs)
End Sub
Private Sub M1
Dim myProcss as Process
-'''''''' Some code
'// Add process exited handler
AddHandler myProcess.Exited, AddressOf myProcess_Exited
myProcss.Start
Me.LaunchedProcesses.Add("p1",myProcss)
End Sub
Private Sub M2
'// Get process
shutDownProcess = DirectCast(Me.LaunchedProcesses.Item("p1"), Process)
'// Remove process exited handler
RemoveHandler shutDownProcess.Exited, AddressOf myProcess_Exited
shutDownProcess.Kill
End Sub
ASKER
This is just some pseudocode to describe the problem. so kill is just to show want I need help with
1> First I execute the M1, the process start with a handler and I add it to the property.
2> Then I run M2, I get the process from the property, and removes the handler from M1
3> I now add a new handler to that process and then I kill it.
The new handler dosen't work instead the old handler still executes
I have also tried to remove the process from the property as soon as I get it but that did not help, still the same problem.
1> First I execute the M1, the process start with a handler and I add it to the property.
2> Then I run M2, I get the process from the property, and removes the handler from M1
3> I now add a new handler to that process and then I kill it.
The new handler dosen't work instead the old handler still executes
I have also tried to remove the process from the property as soon as I get it but that did not help, still the same problem.
I think we are going to need some actual code to spot the problem...
I'm sure what you said is clear to you but it is very vague to the rest of us.
How do you add a handler to a property. From what you gave me it looks like you add a handler to an object that then goes into a class. I just thought maybe by still having it in the class you still had a reference to the object and that might be causing you grief.
Like Idle_Mind said, we need some real code to know what you want to do and are doing wrong.
How do you add a handler to a property. From what you gave me it looks like you add a handler to an object that then goes into a class. I just thought maybe by still having it in the class you still had a reference to the object and that might be causing you grief.
Like Idle_Mind said, we need some real code to know what you want to do and are doing wrong.
ASKER
Here is some "better" code (I hope) to explaine it
Private m_serverProcess As New Hashtable
Private Property LaunchedProcesses() As Hashtable
Get
Return m_serverProcess
End Get
Set(ByVal Value As Hashtable)
m_serverProcess = Value
End Set
End Property
Private Sub Start(ByVal applicationPath As String)
Dim myProcess As Process
Dim server As String = String.Empty
Dim foundProcess As Boolean = False
'// Lookup the real server name
server = m_serverListNames.Item(m_activeServer)
'// Create a new process
myProcess = New Process()
'// Set process settings
With myProcess.StartInfo
.FileName = applicationPath & server & ".exe"
.Arguments() = "/input=True,True"
.CreateNoWindow = False
.ErrorDialog = False
.UseShellExecute = False
.RedirectStandardOutput = True
.RedirectStandardInput = True
.RedirectStandardError = True
.WindowStyle = ProcessWindowStyle.Normal
End With
'// Enable events
myProcess.EnableRaisingEvents = True
'// Add process exited handler
AddHandler myProcess.Exited, AddressOf myProcess_Exited
'// Start process
myProcess.Start()
If Not myProcess.Responding Then
myProcess.Kill()
Else
Me.LaunchedProcesses.Add(server, myProcess)
End If
End Sub
Private Sub [Stop](ByVal applicationPath As String)
Dim shutDownProcess As Process
Dim server As String = String.Empty
Dim foundProcess As Boolean = False
'// Lookup the real server name
server = m_serverListNames.Item(m_activeServer)
'// Get process
shutDownProcess = TryCast(Me.LaunchedProcesses.Item(server), Process)
'// Set process parameters for a controlled shutdown
shutDownProcess.StartInfo.Arguments() = "/shutdown"
'// Remove process exited handler from startup process
RemoveHandler shutDownProcess.Exited, AddressOf myProcess_Exited
'// Add process exited handler for shutdown process
AddHandler shutDownProcess.Exited, AddressOf m_shutDownProcess_Exited
'// Start process
shutDownProcess.Start()
If Not shutDownProcess.Responding Then
shutDownProcess.Kill()
Else
Me.LaunchedProcesses.Remove(server)
End If
End Sub
Private Sub myProcess_Exited(ByVal sender As Object, ByVal e As System.EventArgs)
If Me.InvokeRequired Then
Me.Invoke(New ProcessExited(AddressOf myProcess_Exited), New Object() {sender, e})
Else
MessageBox.Show("Test1")
End If
End Sub
Private Sub m_shutDownProcess_Exited(ByVal sender As Object, ByVal e As System.EventArgs)
If Me.InvokeRequired Then
Me.Invoke(New ProcessExited(AddressOf myProcess_Exited), New Object() {sender, e})
Else
MessageBox.Show("Test2")
End If
End Sub
ASKER
When I execute the stop method, the myProcess_Exited is executeed when the process is exited.
But is should be the m_shutDownProcess_Exited methods
So I must do something wrong :)
But is should be the m_shutDownProcess_Exited methods
So I must do something wrong :)
It looks like to me that you create a process and add it to a collection along with the server name.
Then to stop it you get a handle to it (object ref), but you don't remove it from the collection which leaves a reference still there, then to stop it, you start it again which creates another process.
This seems really strange to me.
See this link:
http://www.thescarms.com/dotnet/Process.aspx
I guess you know that the way you are launching it, it doesn't wait for the process.
So it seems the
If Not myProcess.Responding Then
myProcess.Kill()
code may not get processed at the right time. I'm just saying the process could take a while to start and this code may never get executed.
I assume the processes being launched aren't ones that you have written. Is that true?
.Close or CloseMainWindow might be better methods to use to stop the process instead of kill.
Then to stop it you get a handle to it (object ref), but you don't remove it from the collection which leaves a reference still there, then to stop it, you start it again which creates another process.
This seems really strange to me.
See this link:
http://www.thescarms.com/dotnet/Process.aspx
I guess you know that the way you are launching it, it doesn't wait for the process.
So it seems the
If Not myProcess.Responding Then
myProcess.Kill()
code may not get processed at the right time. I'm just saying the process could take a while to start and this code may never get executed.
I assume the processes being launched aren't ones that you have written. Is that true?
.Close or CloseMainWindow might be better methods to use to stop the process instead of kill.
See code below.
If none of this works, then I am not sure why.
If none of this works, then I am not sure why.
'// Get process
shutDownProcess = TryCast(Me.LaunchedProcesses.Item(server), Process)
'// Remove process from collection
Me.LaunchedProcesses.Remove(shutdownProcess)
'// Remove process exited handler from startup process
RemoveHandler shutDownProcess.Exited, AddressOf myProcess_Exited
ASKER
In my application I use
Private Sub MyApplication_StartupNextI nstance(By Val sender As Object, ByVal e As Microsoft.VisualBasic.Appl icationSer vices.Star tupNextIns tanceEvent Args) Handles Me.StartupNextInstance
End Sub
To pass parameters to the instance, so thats way I start it again but with another argument.
This is the main path
1. I start the process,
2. I add it to a collection
3. I get process from the collection
4. I stop the process
In the stop method I want to change handler of the process object.
In the start methods it points to the method "myProcess_Exited" but when stopping it I want to remove that one and repoint it to another method , this one "m_shutDownProcess_Exited"
so the problem is that in some way I don't manage to remove the pointer/handler to "myProcess_Exited", because when the process exited it still execute the "myProcess_Exited" method, and as you can see in the code I have removed it when I'm in the Stop method
Private Sub MyApplication_StartupNextI
End Sub
To pass parameters to the instance, so thats way I start it again but with another argument.
This is the main path
1. I start the process,
2. I add it to a collection
3. I get process from the collection
4. I stop the process
In the stop method I want to change handler of the process object.
In the start methods it points to the method "myProcess_Exited" but when stopping it I want to remove that one and repoint it to another method , this one "m_shutDownProcess_Exited"
so the problem is that in some way I don't manage to remove the pointer/handler to "myProcess_Exited", because when the process exited it still execute the "myProcess_Exited" method, and as you can see in the code I have removed it when I'm in the Stop method
Isn't this:
'// Start process
shutDownProcess.Start()
starting a brand new process even though you never got rid of the old one?
so if you kill handlers from it in the STOP method and then try to restart a new process and it fails
If Not shutDownProcess.Responding Then
'this does not remove the old process from the collection event though the handlers to it
'have been removed
'Is that what you wanted?
shutDownProcess.Kill()
Else
'this does finally remove it from the collection
Me.LaunchedProcesses.Remov e(server)
End If
'// Start process
shutDownProcess.Start()
starting a brand new process even though you never got rid of the old one?
so if you kill handlers from it in the STOP method and then try to restart a new process and it fails
If Not shutDownProcess.Responding
'this does not remove the old process from the collection event though the handlers to it
'have been removed
'Is that what you wanted?
shutDownProcess.Kill()
Else
'this does finally remove it from the collection
Me.LaunchedProcesses.Remov
End If
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
"starting a brand new process even though you never got rid of the old one? "
No it does not, if you use the internal framwork and MyApplication_StartupNextI nstance in Application event it will not do that, it will execute the same instance again and I can get the argument passed thru the new process start. works great.. So it's the same instance as before,
The kill part code is not the problem here, even if I kill it from Task Manager it still execute the old handler and not the new one. And if I remove it I can't undertand wy this event is executing
No it does not, if you use the internal framwork and MyApplication_StartupNextI
The kill part code is not the problem here, even if I kill it from Task Manager it still execute the old handler and not the new one. And if I remove it I can't undertand wy this event is executing
AWestEng,
Thanks for the information. I'm sorry I don't know why it isn't working either.
Thanks for the information. I'm sorry I don't know why it isn't working either.
ASKER
Yes this sems to be the problem
"Hi, I think I understand why it behaves how it behaves.
A new feature of VB9 allows you to AddHandler for methods with slightly
different signatures than signature of event is. However as I understand it
some hidden routing method/delegate (which routes event to method with
different signature) is created in compile time. And when you uses
RemoveHandler another one is created which results to RemoveHandler removing
handler which had been never attached. So, nothing happens and handler
attached via AddHanlder is still attached.
There are two ways how to prevent this behavior:
1) Is prior VB9 - ensure that method (handler) as EXACTLY same signature as
event (event delegate)
2) Add handler is some way like this
Dim HadlerDelegate = AddressOf MyMethod
AddHandler TheObject.Event, HandlerDelegate
then store HandlerDelegate somewhere and use it with RemoveHandler."
Thx m8
"Hi, I think I understand why it behaves how it behaves.
A new feature of VB9 allows you to AddHandler for methods with slightly
different signatures than signature of event is. However as I understand it
some hidden routing method/delegate (which routes event to method with
different signature) is created in compile time. And when you uses
RemoveHandler another one is created which results to RemoveHandler removing
handler which had been never attached. So, nothing happens and handler
attached via AddHanlder is still attached.
There are two ways how to prevent this behavior:
1) Is prior VB9 - ensure that method (handler) as EXACTLY same signature as
event (event delegate)
2) Add handler is some way like this
Dim HadlerDelegate = AddressOf MyMethod
AddHandler TheObject.Event, HandlerDelegate
then store HandlerDelegate somewhere and use it with RemoveHandler."
Thx m8
ASKER
Good work!! Thx :)
Another thought is... is there not a more graceful way to exit the process instead of .kill?
Maybe the kill happens before the removehandler finishes processing.
See if removing it from the collection first works.