Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

RemoveHandler problem

Posted on 2008-10-17
15
736 Views
Last Modified: 2013-11-07
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
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

Open in new window

0
Comment
Question by:AWestEng
  • 7
  • 7
15 Comments
 
LVL 25

Expert Comment

by:SStory
ID: 22740362
Maybe when you shut it down, you should get it, and then remove it from the collection to avoid the extra reference. I don't know if this is the problem, but it is the first thing that grabbed me.

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.
0
 
LVL 1

Author Comment

by:AWestEng
ID: 22740756
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.
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 22741332
I think we are going to need some actual code to spot the problem...
0
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 
LVL 25

Expert Comment

by:SStory
ID: 22745011
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.
0
 
LVL 1

Author Comment

by:AWestEng
ID: 22747710
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

Open in new window

0
 
LVL 1

Author Comment

by:AWestEng
ID: 22747715
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 :)
0
 
LVL 25

Expert Comment

by:SStory
ID: 22757229
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.



0
 
LVL 25

Expert Comment

by:SStory
ID: 22757306
See code below.

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

Open in new window

0
 
LVL 1

Author Comment

by:AWestEng
ID: 22757433
In my application I use

Private Sub MyApplication_StartupNextInstance(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs) 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

0
 
LVL 25

Expert Comment

by:SStory
ID: 22758565
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.Remove(server)
        End If
0
 
LVL 25

Accepted Solution

by:
SStory earned 500 total points
ID: 22758619
This sounds like it might be promising:
http://www.pcreview.co.uk/forums/thread-3438937.php

read the fourth thing down.
0
 
LVL 1

Author Comment

by:AWestEng
ID: 22765434
"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_StartupNextInstance 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
0
 
LVL 25

Expert Comment

by:SStory
ID: 22767828
AWestEng,

Thanks for the information.  I'm sorry I don't know why it isn't working either.
0
 
LVL 1

Author Comment

by:AWestEng
ID: 22784207
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

 
0
 
LVL 1

Author Closing Comment

by:AWestEng
ID: 31507080
Good work!! Thx :)
0

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

840 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question