我的代码非常简单
Dim temperature As String = SerialPort1.ReadLine.ToString
If temperature.StartsWith("temp") Then
templab.Text = temperature.Substring(4, 2) & "°C"
End If
它给出了
Cross-thread operation not valid: Control 'templab' accessed from a thread other than the thread it was created on.
设置标签文本
我确实搜索了互联网,我找到了一些解决方案,但我的问题不是这个,我过去用visual studio 2008和Windows 7编写了相同的代码,它没有给我任何错误。现在我使用Windows 8和visual studio 2012.如果不调用我怎么能解决这个问题?提前致谢
完整代码:
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
答案 0 :(得分:3)
您需要在线程上调用您的方法。首先使用
进行检查templab.InvokeRequired
创建方法或匿名委托,并在控件上调用它。
来自MSDN
对Windows窗体控件进行线程安全调用 查询控件的InvokeRequired属性。 如果InvokeRequired返回true,则使用委托调用Invoke,该委托对控件进行实际调用。 如果InvokeRequired返回false,则直接调用该控件。 在下面的代码示例中,线程安全调用在ThreadProcSafe方法中实现,该方法由后台线程执行。如果TextBox控件的InvokeRequired返回true,则ThreadProcSafe方法创建一个SetTextCallback实例并将其传递给表单的Invoke方法。这会导致在创建TextBox控件的线程上调用SetText方法,并在此线程上下文中直接设置Text属性。
' 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
有关示例和参考,请参阅here。
答案 1 :(得分:0)
异常告诉您对控件的属性进行了线程间调用...
使用控件的一个要求是不要对它们进行线程间调用
所以要么调用,要么将与contorl交互的代码移动到控件创建的线程中......
如果你的代码执行时间很长并且阻塞UI线程的时间过长,那么唯一的解决办法是调用...