1

非常に単純なコードに問題があります

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
4

2 に答える 2

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

例と参照については、こちらを参照してください。

于 2013-04-20T20:31:45.927 に答える
0

例外は、コントロールのプロパティへのスレッド間呼び出しがあることを示しています...

コントロールを操作するための 1 つの要件は、コントロールへのスレッド間呼び出しを持たないことです。

そのため、コントロールとの対話用のコードを呼び出すか、コントロールが作成されたスレッドに移動します...

コードの実行時間が長く、UI スレッドのブロックが長すぎる場合、唯一の解決策は ... を呼び出すことです。

于 2013-04-20T20:32:24.843 に答える