跨线程访问vb.net中的串行端口问题
问题描述:
你好,
我正在为某种硬件开发应用程序,其中我想通过串行端口从硬件设备接收数据,并将此数据存储在变量中并在文本框中显示.
但是当我尝试在文本框中显示时,它给出了线程交叉检测的错误.
跨线程操作无效:控制TextBox1是从创建该线程的线程之外的线程访问的"
Hello,
I am developing an application for some kind of hardware in which i want to receive data from hardware device through serial port and store this data in a variable and display it in textbox.
but when i try to display in text box then it gives an error of Thread Cross detection.
"Cross-thread operation not valid: Control TextBox1 accessed from a thread other than the thread it was created on"
Imports System.Data.OleDb
Imports System.IO.Ports
Public Class Student_Entry
Dim str12 As String
Dim cn As OleDbConnection
Dim cmd As OleDbCommand
Dim dr As OleDbDataReader
Dim da As OleDbDataAdapter
Dim str As String
Dim icount As Integer
Dim rcount As Integer
Dim data As DataTable
Dim response As String, deviceadd As String
Dim c As Integer, i As Integer
Dim datareceive As String
Dim deviceNum As Integer, devicetemp As Integer
Private Sub Student_Entry_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Try
For Each sp As String In SerialPort.GetPortNames
portcode = sp.ToString()
Next
With SerialPort1
.PortName = portcode
.BaudRate = 115200
.Parity = IO.Ports.Parity.None
.DataBits = 8
.StopBits = IO.Ports.StopBits.Two
.Open()
End With
Catch ex As Exception
MsgBox("Please Change Port setting")
End Try
End Sub
''Receiving data from serial port when device active
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
On Error Resume Next
With SerialPort1
response = ""
datareceive = SerialPort1.ReadExisting()
For i As Integer = 1 To Len(datareceive)
c = Asc(Mid(datareceive, i, 2))
response = response & Hex(c) & " "
Next
If Mid(response, 1, 2) = "7B" And Mid(response, 31, 2) = "7D" And Len(response) = 33 Then
deviceadd = Mid(response, 14, 11)
MsgBox(deviceadd) ''This msg box working properly
TextBox1.Text = deviceadd ''But the value of deviceadd is not display in TextBox1 it generates cross thread detection problem
deviceNum = Mid(response, 23, 1)
devicetemp = Mid(response, 1, 23)
''ans = Mid(response, 25, 1)
End If
End With
End Sub
请给我适当的解决方案,以解决此问题
谢谢哥们...
Please Give me proper solution for this problem
Thanks buddy...
答
好确定最后我已经解决了这个问题,我想和我的朋友们分享一下...
我已经清楚地添加了此功能....
首先,我检查是否有任何跨线程情况发生,然后我将其修复
Ok Ok Finally I had got solution for this problem and i would like to share it with my friends.....
I have added this function working clearly....
First I check there is any cross thread condition occur if yes then i fix it
Imports System.Data.OleDb
Imports System.IO.Ports
Public Class Student_Entry
Dim str12 As String
Dim cn As OleDbConnection
Dim cmd As OleDbCommand
Dim dr As OleDbDataReader
Dim da As OleDbDataAdapter
Dim str As String
Dim icount As Integer
Dim rcount As Integer
Dim data As DataTable
Dim response As String, deviceadd As String
Dim c As Integer, i As Integer
Dim datareceive As String
Dim deviceNum As Integer, devicetemp As Integer
Private Sub Student_Entry_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Try
For Each sp As String In SerialPort.GetPortNames
portcode = sp.ToString()
Next
With SerialPort1
.PortName = portcode
.BaudRate = 115200
.Parity = IO.Ports.Parity.None
.DataBits = 8
.StopBits = IO.Ports.StopBits.Two
.Open()
End With
Catch ex As Exception
MsgBox("Please Change Port setting")
End Try
End Sub
''Receiving data from serial port when device active
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
On Error Resume Next
With SerialPort1
response = ""
datareceive = SerialPort1.ReadExisting()
For i As Integer = 1 To Len(datareceive)
c = Asc(Mid(datareceive, i, 2))
response = response & Hex(c) & " "
Next
If Mid(response, 1, 2) = "7B" And Mid(response, 31, 2) = "7D" And Len(response) = 33 Then
deviceadd = Mid(response, 14, 11)
MsgBox(deviceadd) ''This msg box working properly
''Instead of below step we calling a method
'' TextBox1.Text = deviceadd
call chekthread()
End If
End With
End Sub
''Check Thread cross
Private Sub chekthread()
Try
If (TextBox1.InvokeRequired) Then
TextBox1.Invoke(New MethodInvoker(AddressOf chekthread), New Object() {Text})
End If
TextBox1.Text = deviceadd.ToString()
多亏了我的自我
Thanks to my self
,或者在4.0中,您可以像这样调用文本框:
Or in 4.0 you can call the textbox like this:
'Receiving data from serial port when device active
Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
On Error Resume Next
With SerialPort1
response = ""
datareceive = SerialPort1.ReadExisting()
For i As Integer = 1 To Len(datareceive)
c = Asc(Mid(datareceive, i, 2))
response = response & Hex(c) & " "
Next
If Mid(response, 1, 2) = "7B" And Mid(response, 31, 2) = "7D" And Len(response) = 33 Then
deviceadd = Mid(response, 14, 11)
MsgBox(deviceadd)
Me.Invoke(Sub()
TextBox1.Text = deviceadd
End Sub)
End If
End With
End Sub
您不能直接访问UI控件来自创建线程之外的线程.为此,您必须使用IsInvokeRequired
InvokeRequired
属性和Invoke()
方法. Google用这些术语来查找更多信息.
You cannot directly access a UI control from threads other than the one that created it. To do so, you have to use theIsInvokeRequired
InvokeRequired
property and theInvoke()
method. Google these terms to find out more.