Results 1 to 16 of 16

Thread: X close button not closing the Form (hangs)

  1. #1

    Thread Starter
    Addicted Member beic's Avatar
    Join Date
    Jun 2012
    Posts
    150

    Question X close button not closing the Form (hangs)

    Hi there,

    I'm new in the .NET world, just trying to port over to the .NET platform from VS6 (Visual Basic 6).

    I wish to close the main Form with the "x" button while it's Connected to the Serial Port, but the whole form freezes (hangs) without any error.

    Any help would be much appreciated, thanks!

    Code:
    Imports System
    Imports System.Threading
    Imports System.IO.Ports
    Imports System.ComponentModel
    
    Public Class frmMAIN
    
        Dim myPorts As Array
        Delegate Sub SetTextCallBlack(ByVal [text] As String)
    
        Public Sub serDisconnect()
    
            If ser.IsOpen = True Then
                ser.Close()
                cmdConnect.Enabled = True
                cmdDisconnect.Enabled = False
                cboPorts.Enabled = True
                cboBaud.Enabled = True
            End If
    
        End Sub
    
        Private Sub frmMAIN_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
            Me.Text = "Serial Test"
    
            cmdConnect.Enabled = False
    
            myPorts = IO.Ports.SerialPort.GetPortNames()
    
            With cboPorts
                .Items.AddRange(myPorts)
                If .Items.Count() > 0 Then
                    .SelectedIndex = 0
                Else
                    cmdConnect.Enabled = False
                    cmdDisconnect.Enabled = False
                    cboPorts.Enabled = False
                    cboBaud.Enabled = False
                End If
            End With
    
            cboBaud.SelectedIndex = 0
    
            If cboPorts.Items.Count <= 0 Then
                cmdConnect.Enabled = False
            Else
                cmdConnect.Enabled = True
            End If
    
        End Sub
    
        Private Sub cmdConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdConnect.Click
    
            ser.BaudRate = cboBaud.Text
            ser.PortName = cboPorts.Text
    
            If ser.IsOpen = False Then
                ser.Open()
                cmdConnect.Enabled = False
                cmdDisconnect.Enabled = True
                cboPorts.Enabled = False
                cboBaud.Enabled = False
            End If
    
        End Sub
    
        Private Sub cmdDisconnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdDisconnect.Click
    
            Call serDisconnect()
    
        End Sub
    
        Private Sub ser_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles ser.DataReceived
    
            ReceivedText(ser.ReadExisting())
    
        End Sub
    
        Private Sub ReceivedText(ByVal [text] As String)
    
            If txtOutput.InvokeRequired Then
                Dim x As New SetTextCallBlack(AddressOf ReceivedText)
                Me.Invoke(x, New Object() {(text)})
            Else
                lblPotVal.Text = [text]
                txtOutput.Text &= [text]
            End If
    
        End Sub
    
        Private Sub frmMAIN_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
            Call serDisconnect()
            Application.Exit()
            End
        End Sub
    
    End Class

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: X close button not closing the Form (hangs)

    Firstly, why are you calling Application.Exit and then using End? Never use End at all but, if you were going to, calling Application.Exit first would be pointless. The point of Application.Exit is to exit the application cleanly while the point of End is to dump it out of memory unceremoniously there and then. Get rid of the End statement and never use it again.

    As for the issue, debug your code. A hang is either an infinite loop or a method that doesn't return. The debugger will tell you which and where it is. I would guess that it's in serDisconnect somewhere but you don't have to guess, so neither should we.

  3. #3

    Thread Starter
    Addicted Member beic's Avatar
    Join Date
    Jun 2012
    Posts
    150

    Re: X close button not closing the Form (hangs)

    Quote Originally Posted by jmcilhinney View Post
    1. Get rid of the End statement and never use it again.
    2. The debugger will tell you which and where it is. I would guess that it's in serDisconnect somewhere but you don't have to guess, so neither should we.
    Thank you for your fast reply!

    - Removed the End statement.
    - Tried to Debug, but there is no error shown.

    Weird thing is that, when I press the Disconnect button and after the "x" button, it's closing as it should without hanging the Form.

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: X close button not closing the Form (hangs)

    Get rid of the Application.Exit call too. If this is your startup form then closing it will exit the app anyway, so calling Application.Exit is also pointless and possibly doing so could cause the issue.

    That said, did you actually debug properly? Does that call to serDisconnect return, because that's what I specifically called out as something you should be looking at?

  5. #5
    Lively Member
    Join Date
    Aug 2014
    Posts
    65

    Re: X close button not closing the Form (hangs)

    If it is an infinite loop like jmcilhinney suggests it won't show as an error. The code will just repeat. As an example if you have a loop that can never end because the end condition is never met (like do a loop until countnumber = 10 but you forget to do countnumber +1). The code doesn't see this as a bug so there is no error. You will need to set breakpoints on the important parts of the program to see if it repeats the code where you don't expect it or that it stops somewhere unexpected. In this case I would suggest the subroutines frmMAIN_FormClosing and serDisconnect().

    Also I wonder if you need Application.Exit() in the closing area. I ain't sure but I think that code is calling the frmMAIN_FormClosing subroutine and which runs the code Application.Exit() again which calls the subroutine frmMAIN_FormClosing ect. Maybe this is the infinite loop problem.

  6. #6
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,988

    Re: X close button not closing the Form (hangs)

    Saying that you "tried to debug but there was no error" is a very telling statement. What JMC meant by debugging the code was not "run it and see whether or not it throws an error." In this case, there are a variety of techniques you could try, so 'debugging' doesn't have to mean just one thing. Usually, it is shorthand for, "Put a breakpoint on a line and go from there", or something along those lines, but there are other options here.

    The first thing I would try would be to hit break when the program hangs. You will be taken to the currently running line. At that time, press F11. Either you will go to the next line (in which case you have an infinite loop), or else you will not (which sounds much more likely, in this case). If F11 does not take you to the next line, then not only do you know that the program is frozen, but you know which line is causing the problem. Knowing that would be fairly crucial.

    The alternative approach would be to realize that the problem is almost certainly in serDisconnect, so put a breakpoint on the If statement in there, and when execution stops on the breakpoint, hit F11 until the program hangs. The last line executed at the time of the hang is the problem.
    My usual boring signature: Nothing

  7. #7

    Thread Starter
    Addicted Member beic's Avatar
    Join Date
    Jun 2012
    Posts
    150

    Re: X close button not closing the Form (hangs)

    First of all thank you to all for the help and support!

    In the meanwhile I Googled around the internet about the Serial Port .close() freezing the Form on close, it has some weird bug from vb.net 2005 to 2010 (MS didn't have time to fix it, I guess, that certain bug still persists).

    But, that was not my issue, in my case what was freezing the Form exiting with "X" button from the application was in this line:

    Code:
    Me.Invoke(x, New Object() {(text)})
    I changed to:

    Code:
    Me.BeginInvoke(x, New Object() {(text)})
    And now it's working as it should.

    But, can someone please explain me why, and what was the real issue that I couldn't see it by Debugging it?

    Thank you!
    Last edited by beic; Sep 21st, 2022 at 06:53 PM. Reason: typo

  8. #8
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: X close button not closing the Form (hangs)

    The Invoke method is synchronous, i.e. it doesn't return until the invoked method does. BeginInvoke is asynchronous, i.e. it returns immediately, not waiting for the invoked method to complete. I would guess that your call to Invoke would never return because the UI thread was blocked, thus preventing the invoked method completing. You may have had a deadlock somewhere.

  9. #9

    Thread Starter
    Addicted Member beic's Avatar
    Join Date
    Jun 2012
    Posts
    150

    Re: X close button not closing the Form (hangs)

    Quote Originally Posted by jmcilhinney View Post
    The Invoke method is synchronous, i.e. it doesn't return until the invoked method does. BeginInvoke is asynchronous, i.e. it returns immediately, not waiting for the invoked method to complete. I would guess that your call to Invoke would never return because the UI thread was blocked, thus preventing the invoked method completing. You may have had a deadlock somewhere.
    Thank you for your explanation it helped me a lot!

    It was clearly as you mentioned a "deadlock" because Invoke would never return because the UI thread was blocked...

    The
    Code:
    frmMAIN_FormClosing
    call couldn't execute properly the command
    Code:
    ser.Close()
    in Sub
    Code:
    serDisconnect()
    because it was stuck in the endless loop function:

    Code:
       Private Sub ser_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles ser.DataReceived
    
            ReceivedText(ser.ReadExisting())
    
        End Sub
    
        Private Sub ReceivedText(ByVal [text] As String)
    
            If txtOutput.InvokeRequired Then
                Dim x As New SetTextCallBlack(AddressOf ReceivedText)
                Me.Invoke(x, New Object() {(text)})
            Else
                lblPotVal.Text = [text]
                txtOutput.Text &= [text]
            End If
    
        End Sub
    That's why the Disconnect command button was working just fine, but the Form "x" close button freezes the whole Form.

    If I'm correct.
    Last edited by beic; Sep 22nd, 2022 at 05:10 AM. Reason: typo

  10. #10
    Hyperactive Member gaouser's Avatar
    Join Date
    Mar 2022
    Location
    Near the User32.dll
    Posts
    386

    Re: X close button not closing the Form (hangs)

    its happening because its in endless loop to read something. you should stay on vb6. vb6 is more com friendly

  11. #11
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,754

    Re: X close button not closing the Form (hangs)

    Give this a try,

    Code:
        Private Sub frmMAIN_FormClosing(sender As Object,
                                        e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
            If serDisconnect() Then
                e.Cancel = True 'port was open
                'close again
                Dim t As Task = Task.Run(Sub()
                                             Me.BeginInvoke(Sub()
                                                                Me.Close()
                                                            End Sub)
                                         End Sub)
            End If
        End Sub
    
        Public Function serDisconnect() As Boolean
            Dim rv As Boolean = False
            If ser.IsOpen Then
                rv = True 'port was open
                ser.Close()
                cmdConnect.Enabled = True
                cmdDisconnect.Enabled = False
                cboPorts.Enabled = True
                cboBaud.Enabled = True
            End If
            Return rv
        End Function
    
        Private Sub ser_DataReceived(sender As Object,
                                       e As IO.Ports.SerialDataReceivedEventArgs) Handles ser.DataReceived
            ReceivedText(ser.ReadExisting)
        End Sub
    
        Private Sub ReceivedText([text] As String)
            Me.BeginInvoke(Sub()
                               lblPotVal.Text = [text]
                               txtOutput.Text &= [text]
                           End Sub)
        End Sub
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  12. #12

    Thread Starter
    Addicted Member beic's Avatar
    Join Date
    Jun 2012
    Posts
    150

    Re: X close button not closing the Form (hangs)

    Quote Originally Posted by dbasnett View Post
    Give this a try,

    Code:
        Private Sub frmMAIN_FormClosing(sender As Object,
                                        e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
            If serDisconnect() Then
                e.Cancel = True 'port was open
                'close again
                Dim t As Task = Task.Run(Sub()
                                             Me.BeginInvoke(Sub()
                                                                Me.Close()
                                                            End Sub)
                                         End Sub)
            End If
        End Sub
    
        Public Function serDisconnect() As Boolean
            Dim rv As Boolean = False
            If ser.IsOpen Then
                rv = True 'port was open
                ser.Close()
                cmdConnect.Enabled = True
                cmdDisconnect.Enabled = False
                cboPorts.Enabled = True
                cboBaud.Enabled = True
            End If
            Return rv
        End Function
    
        Private Sub ser_DataReceived(sender As Object,
                                       e As IO.Ports.SerialDataReceivedEventArgs) Handles ser.DataReceived
            ReceivedText(ser.ReadExisting)
        End Sub
    
        Private Sub ReceivedText([text] As String)
            Me.BeginInvoke(Sub()
                               lblPotVal.Text = [text]
                               txtOutput.Text &= [text]
                           End Sub)
        End Sub
    Thanks, but I'm getting Error BC30002 Type 'Task' is not defined.

    Code:
    Imports System.Threading.Tasks.Task
    is included.
    Last edited by beic; Sep 24th, 2022 at 04:11 PM. Reason: typo

  13. #13
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: X close button not closing the Form (hangs)

    Quote Originally Posted by beic View Post
    Thanks, but I'm getting Error BC30002 Type 'Task' is not defined.

    Code:
    Imports System.Threading.Tasks.Task
    is included.
    Why are you importing a class and not the namespace the class is a member of? Also, are you targeting .NET Framework or .NET Core? If the former, are you targeting at least version 4.0, because that's when that class was introduced?

  14. #14

    Thread Starter
    Addicted Member beic's Avatar
    Join Date
    Jun 2012
    Posts
    150

    Re: X close button not closing the Form (hangs)

    Quote Originally Posted by jmcilhinney View Post
    Why are you importing a class and not the namespace the class is a member of? Also, are you targeting .NET Framework or .NET Core? If the former, are you targeting at least version 4.0, because that's when that class was introduced?
    What do you mean? If I use only:
    Code:
    System.Threading.Tasks
    I'm getting Error BC30456 'Run' is not a member of 'Task'.

    I'm using .NET Framework 4 Client Profile.

  15. #15
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: X close button not closing the Form (hangs)

    Do you understand what an Imports statement actually does? It appears not and you're just throwing stuff at the wall. The point of an Imports statement is to allow you to use the members of what you import without qualification. That's it, that's all. You don;t need any Imports statements at all but, if you don't use any, you have to fully-qualify everything. For instance, if you have a type ParentNamespace.ChildNamespace.SomeClass then you can do this in your code:
    vb.net Code:
    1. Dim something As ParentNamespace.ChildNamespace.SomeClass
    That's fine for a one-off but it's annoying to do repeatedly so, generally, you would do this:
    vb.net Code:
    1. Imports ParentNamespace.ChildNamespace
    and this:
    vb.net Code:
    1. Dim something As SomeClass
    You can use the type unqualified because you have imported the namespace. In your case, if you want to use the System.Threading.Tasks.Task class unqualified then you need to import the System.Threading.Tasks namespace, not the System.Threading.Tasks.Task class. You haven't imported that namespace so trying to use types that are members of it unqualified won't work. Importing the class is not a solution to your original problem.

    You say that you're using the .NET Framework 4.0 Client Profile. Do you know what that actually means? The Client Profile is a smaller version of the .NET Framework that includes what most client applications need. Do you know how they make it smaller? They take stuff out. If you're trying to use a type or member that they have taken out then that would explain why you're being told it doesn't exist. I'm not sure whether Task.Run should be part of the Client Profile or not but you're error message suggests not. That's something you need to check for. If it's not then you need to either target the full Framework or find a different way to achieve your aim. I've had a quick look for specific documentation and can't find it. The simplest option to check might be to change the target Framework from 4.0 Client Profile to 4.0 and see whether that method becomes available. If it does then it's safe to say that it's not part of the Client Profile.

  16. #16
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: X close button not closing the Form (hangs)

    For the record, you can import a class but, as for a namespace, the point is to use its members unqualified. If you import the System.Threading.Tasks.Task class then you would use its Run method unqualified, much as you do a member of a module. That's rarely done though, as it is generally considered to make code harder to read rather than easier. What is more common is importing classes to alias them in order to avoid name clashes. For instance, you will often see this done in apps that automate Microsoft Word:
    vb.net Code:
    1. Imports Word = Microsoft.Office.ObjectModel.Word
    After that, you can just use Word in code to mean Microsoft.Office.ObjectModel.Word. You might also use an alias for long type names, e.g.
    vb.net Code:
    1. Imports MLTN = ParentNamespace.ChildNamespace.MyLongTypeName
    You can then use MLTN in code to refer to that type.

    These are fairly unusual occurrences though. In the vast majority of cases, you'll import namespace only. Also, it's generally preferable to import at the project level, on the References page of the project properties, rather than at athe file level, unless you specifically need an import only for that file or you're trying to avoid name clashes. If you open that page, you'll see all those namespaces that are imported by default that you have taken for granted, e.g. System and System.Windows .Forms.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width