Christos Mitsis
Christos Mitsis

Reputation: 167

Cross-thread operation invalid

i have a problem with a very simple code

Dim temperature As String = SerialPort1.ReadLine.ToString

        If temperature.StartsWith("temp") Then

            templab.Text = temperature.Substring(4, 2) & "°C"
        End If

and it gives

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

on setting the text of the label

I did searched the internet for this and i found some solutions but my problem isn't this, i had written the same code in the past with visual studio 2008 and windows 7 and it didnt give me any error. Now i work with windows 8 and visual studio 2012. How could i solve this without invoke? Thanks in advance

Full Code:

Public Class Form1


    Private Sub SerialPort1_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        Dim temperature As String = SerialPort1.ReadLine.ToString

        If temperature.StartsWith("temp") Then

            templab.Text = temperature.Substring(4, 2) & "°C"
        End If
        ' My.Computer.Audio.Play("C:\Users\Chris\Desktop\ROMANTIC MUSIC INSTRUMENTAL, PIANO AND SAXOPHONE.wav", AudioPlayMode.Background)
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        SerialPort1.Open()
    End Sub
End Class

Upvotes: 1

Views: 1569

Answers (2)

bash.d
bash.d

Reputation: 13207

You will need to invoke your method on the thread. First check using

templab.InvokeRequired

create either a method or an anonymous delegate and invoke it on the control.

From MSDN

To make a thread-safe call to a Windows Forms control Query the control's InvokeRequired property. If InvokeRequired returns true, call Invoke with a delegate that makes the actual call to the control. If InvokeRequired returns false, call the control directly. In the following code example, a thread-safe call is implemented in the ThreadProcSafe method, which is executed by the background thread. If the TextBox control's InvokeRequired returns true, the ThreadProcSafe method creates an instance of SetTextCallback and passes that to the form's Invoke method. This causes the SetText method to be called on the thread that created the TextBox control, and in this thread context the Text property is set directly.

' This event handler creates a thread that calls a  
' Windows Forms control in a thread-safe way. 
 Private Sub setTextSafeBtn_Click( _
 ByVal sender As Object, _
 ByVal e As EventArgs) Handles setTextSafeBtn.Click

     Me.demoThread = New Thread( _
     New ThreadStart(AddressOf Me.ThreadProcSafe))

     Me.demoThread.Start()
 End Sub 


' This method is executed on the worker thread and makes 
' a thread-safe call on the TextBox control. 
 Private Sub ThreadProcSafe()
   Me.SetText("This text was set safely.")
 End Sub


' This method demonstrates a pattern for making thread-safe 
' calls on a Windows Forms control.  
' 
' If the calling thread is different from the thread that 
' created the TextBox control, this method creates a 
' SetTextCallback and calls itself asynchronously using the 
' Invoke method. 
' 
' If the calling thread is the same as the thread that created 
' the TextBox control, the Text property is set directly.  

 Private Sub SetText(ByVal [text] As String)

 ' InvokeRequired required compares the thread ID of the 
 ' calling thread to the thread ID of the creating thread. 
 ' If these threads are different, it returns true. 
  If Me.textBox1.InvokeRequired Then 
     Dim d As New SetTextCallback(AddressOf SetText)
     Me.Invoke(d, New Object() {[text]})
 Else 
     Me.textBox1.Text = [text]
 End If 
End Sub

See here for an example and reference.

Upvotes: 3

DarkSquirrel42
DarkSquirrel42

Reputation: 10257

the exception tells you that you have an inter thread call to a control's property ...

one Requirement for working with controls is not to have inter thread calls to them

so either invoke, or move your code for the interaction with the contorl to the thread the control was created in...

if your code has long execution times and would block the UI thread too long, the ONLY solution is to invoke ...

Upvotes: 0

Related Questions