locked
Application hanging on Serialport .Close method

    Question

  • This one has me stumped.  I've created a class to interface with a device on a comm port.  I've decalred the serial port:

    Private WithEvents moPort as System.IO.Ports.SerialPort

    In the New event, I create the port and open it, works great.  I communicate just fine, handle everthing going in, coming out no problem.  When I go to close the port, by just a .Close command in a "Disconnect" method I've defined or in the IDisposeable implementation, the entire program hangs up.  I can hit Pause in the IDE and it highlights the "moPort.Close" line, the call stack always shows something like:

    [In a sleep, wait, or join]
    [External Code]
    Executablename!ProgramName.ClassName.Dispose(boolean Disposing = True)
    Executablename!ProgramName.ClassName.Dispose()

    I've let it set here for a few minutes and it never comes back, I have to hit the "Stop" button in the IDE to shut it down .  Has anyone seen this or have any idea what I'm doing wrong?

    Wednesday, June 28, 2006 9:55 PM

All replies

  • If you have the boolean active, can't you go:

    If Executablename!ProgramName.ClassName.Dispose() Then
        'Successful close
    Else
        MsgBox("Whoopsie!")
    End If

    Or does it hang before it even registers this?

    Wednesday, June 28, 2006 11:21 PM
  • It hangs in the dispose method itself:

    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        
    If Not Me.disposedValue Then
             
    If disposing Then
                  
    ' free unmanaged resources when explicitly called
                  
    Try
                       
    If moPort IsNot Nothing Then
                            
    If moPort.IsOpen Then
                                 
    moPort.Close()     '<--- Hangs here
                            
    End If
                            
    moPort.Dispose()
                       
    End If
                  
    Catch ex As System.Exception
                      
    'don't care
                  
    Finally
                      
    moPort = Nothing
                  
    End Try
             
    End If
             
    ' TODO: free shared unmanaged resources
        
    End If
        
    Me.disposedValue = True
    End Sub

    Wednesday, June 28, 2006 11:41 PM
  • I don't seem to have the System.IO.Ports namespace. Are you using VS.NET2003 or VS.NET2005?
    Thursday, June 29, 2006 1:28 AM
  • Sorry, forgot to include that   VS '05 Professional on XP SP2.
    Thursday, June 29, 2006 2:31 PM
  • Ahh damn. I can't help you sorry. I'm a VS.NET2003 Man.
    Thursday, June 29, 2006 2:46 PM
  • This problem is a frequent topic on these forums.  This thread is relevant.  It appears the Close() method is prone to deadlock but there has never been a good diagnosis.  Avoid opening and closing the port more than once might help...

    Thursday, June 29, 2006 5:26 PM
    Moderator
  • Great thread, thank you for suggesting it!  Not sure why it didn't come up when I search here initially for this.. /shrug.  I have one open (called right after the class is initialized) and one close (called just before setting the class object = nothing).  The port remains open and active while the class is in use.

    I have a thread in the form the class is created in that polls the comm port every few seconds through this class.   In the form close event I kill the thread (.Abort and = nothing) then I attempt to .Disconnect (.close()) and .Dispose the serial port class I've created.  It still seems to deadlock on either the .Close() in the disconnect or,  if I  comment out the .Disconnect, hangs in the .Close() in the Dispose method.

    Any other ideas?

    Thursday, June 29, 2006 7:46 PM
  • Having the thread that does the reading call Open, Close and Dispose might be a good idea.  I really can't promise it would work. 

    Thursday, June 29, 2006 7:57 PM
    Moderator
  • The class raises it's own events based on what's received in the DataReceived event for the serial port control, and monitoring isn't begun until after a couple things have been recieved and evaluated from the device it's connected to.  So I'm not sure that I could do that without scrapping what I've got so far and attemtping to code around the deadlock issue. 

    Thanks for the ideas, though.

    Thursday, June 29, 2006 8:37 PM
  • Not sure what difference it makes in the spookyness that is VB.Net,  but I moved the shutdown code to it's own routine (from FormClosing) and explicitly called it prior to form=nothing and that seemes to have resolved the deadlock somehow.
    Thursday, June 29, 2006 9:00 PM
  • Hmm, try it at least 20 times.  That's classic threading spookiness...

    Thursday, June 29, 2006 9:12 PM
    Moderator
  • Seems to be working without a lockup.  I just moved the code in the FormClosing to a "Shutdown" method, and rather than just:

    formvar = Nothing

    I do:

    formvar.ShutDown
    formvar = Nothing

    And that seems to work.  If I do just the = nothing then it locks up again.  It has to be some type of thread-timing issue that is beyond my ability to fathom.

    Thanks again 'bugz :)

    Thursday, June 29, 2006 10:22 PM
  • I would say it's a threading issue: threads are easy when they work, when they break it's extremely hard to figure out what's going on. With the Serial Port, because it raises events on a different thread, it can make it all the more difficult.

    I've placed all serial port stuff in its own class in its own thread, and don't have any problems (uh-oh, shouldn't have said that...).

    Friday, June 30, 2006 12:34 PM
    Moderator