Error: Cross-thread operation not valid: Control 'TextBox1' accessed from a thread other than the thread it was created on.

After doing some research online I found when I add Control.CheckForIllegalCrossThreadCalls = False it works but I feel like that is not the proper way to handle this error. If anyone has a better way of handling this by starting a new thread or something please show me how.

Visual Studio 2008 Dev Edition

Imports sds = System.Data.SqlClient
Imports System.Configuration
Imports System.IO
Imports System.Data.SqlClient
Imports System.IO.Ports
Imports System.Threading
Public Class Form1
    Dim WithEvents mySerialPort As New SerialPort("COM1")

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Control.CheckForIllegalCrossThreadCalls = False 'when removed I recieve error
        mySerialPort.BaudRate = 9600
        mySerialPort.Parity = Parity.None
        mySerialPort.StopBits = StopBits.One
        mySerialPort.DataBits = 8
        mySerialPort.Handshake = Handshake.None

        AddHandler mySerialPort.DataReceived, AddressOf DataReceviedHandler
        mySerialPort.Open()
    End Sub

    Private Sub DataReceviedHandler(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) Handles mySerialPort.DataReceived
        mySerialPort = CType(sender, SerialPort)

        Dim int As Integer = mySerialPort.BytesToRead
        Dim indata As String = mySerialPort.ReadExisting()

        MsgBox(indata)
        TextBox1.Text = indata

    End Sub

Here's a thread-safe way to assign text to the (UI-thread) control:

    Delegate Sub SetTextCallback(newString As String)

    Private Sub SetText(ByVal newString As String)

        ' Calling from another thread? -> Use delegate
        If Me.TextBox1.InvokeRequired Then
            Dim d As New SetTextCallback(AddressOf SetText)
            ' Execute delegate in the UI thread, pass args as an array
            Me.Invoke(d, New Object() {newString})
        Else ' Same thread, assign string to the textbox
            Me.TextBox1.Text = newString
        End If
    End Sub

Now, in your code line 29 becomes: SetText(indata)
Procedure SetText checks if the call comes from another thread: Me.TextBox1.InvokeRequired and calls the delegate if it does. Otherwise call comes from the same thread and the text can be assigned in a normal way.

HTH

(I checked "Markdown Syntax: Formatting Help" but I didn't find a way to use syntax formatting for the code part. I really miss BBCODEs... :) )

This article has been dead for over six months. Start a new discussion instead.