跨线程操作无效

时间:2013-04-20 20:25:55

标签: vb.net multithreading serial-port

我的代码非常简单

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

2 个答案:

答案 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线程的时间过长,那么唯一的解决办法是调用...

相关问题