Reputation: 167
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
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
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