0

I'm trying to set up a simple TCP server in a separate form to my main one (to simulate an arduino board while I'm testing).

I've got a Start/Stop button and a label showing the server status underneath.

I think I've finally got these threads handled properly but I've still got one exception coming up that only occurs when I close the form while the thread is running. I'm not sure why though as the thread is what accesses the Label throwing the exception and the thread should be closed.

The error is : "A first chance exception of type 'System.ObjectDisposedException' occurred in System.Windows.Forms.dll" on the line "Me.Invoke(d, New Object() {status})" in UpdateStatus()

The code is below, I've caught the exception which should do the job but I'd like to know if I'm doing something inherently wrong. Any suggestions would be greatly appreciated, thanks

Imports System.Net
Imports System.Net.Sockets
Imports System.Threading

Public Class ArduinoSimulator

Dim running As Boolean = False

Dim serverThread As New Threading.Thread(AddressOf StartServer)

Private Sub startserver()

    While (running)
        Dim time As String = DateTime.Now.Second.ToString
        updateStatus(time)
    End While

End Sub

Private Sub StartStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartStop.Click

    If Not running Then

        running = True
        updateButton("Stop Simulation")

        Dim serverThread As New Threading.Thread(AddressOf startserver)
        serverThread.IsBackground = True
        serverThread.Start()
    Else
        running = False
        updateButton("Start Simulation")
        updateStatus("Not Started")

        Try
            serverThread.Abort()
        Catch ex As Exception
        End Try

    End If
End Sub


Delegate Sub UpdateStatusCallback(ByVal status As String)

Private Sub updateStatus(ByVal status As String)

    Try

        If Me.InvokeRequired Then
            Dim d As New UpdateStatusCallback(AddressOf updateStatus)
            Me.Invoke(d, New Object() {status})
        Else
            StatusLabel.Text = status
        End If

    Catch ex As Exception

    End Try

End Sub

Delegate Sub UpdateButtonCallback(ByVal buttontext As String)

Private Sub updateButton(ByVal buttontext As String)

    If Me.InvokeRequired Then
        Dim d As New UpdateStatusCallback(AddressOf updateStatus)
        Me.Invoke(d, New Object() {buttontext})
    Else
        StartStop.Text = buttontext
    End If

End Sub

Private Sub ArduinoSimulator_close(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Me.FormClosing
    Main.ArduinoConnectionSimulatorToolStripMenuItem.Checked = False
    running = False
    Try
        serverThread.Abort()
    Catch ex As Exception
    End Try
End Sub

End Class
  • When I Google for "Thread.Abort" I get *images of disgust* as result #3: http://imgur.com/a/AXues – usr Nov 06 '13 at 17:15
  • Here's why you shouldn't use it: http://stackoverflow.com/questions/421389/is-this-thread-abort-normal-and-safe – usr Nov 06 '13 at 17:16
  • 2
    There is very little point in burning up a thread to update a label with a value that can only change once a second. And to do so thousands of times per second. Use a Timer instead. – Hans Passant Nov 06 '13 at 17:31
  • This is happening because the background thread is trying to update after the form has been destroyed. When your program exits, it first destroys the form, then does other cleanup and shuts down. The background thread is running full-tilt, meaning that it will try to do the update after the form is destroyed but before the program is completely shut down. Do as Hans recommended and use a [Timer](http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx) to update once per second. – Jim Mischel Nov 06 '13 at 17:45

0 Answers0