Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net-关闭窗体时出现交叉线程异常_Vb.net_Multithreading_Formclosing - Fatal编程技术网

Vb.net-关闭窗体时出现交叉线程异常

Vb.net-关闭窗体时出现交叉线程异常,vb.net,multithreading,formclosing,Vb.net,Multithreading,Formclosing,我正在开发一个应用程序,从串口通信端口读取数据。 简而言之,它的工作原理是这样的:当你在酒吧或餐馆工作时,在你可以在登记簿中输入一些东西之前,你必须扫描一种卡片。如果这张卡返回的数字正确,你可以输入一些东西 因此,必须有一个表单来监听串行端口,并检查是否有人扫描了一张卡,以及它是否是一张具有良好权限的卡 如果此人拥有良好的权利,则可以关闭该表单,并调用另一个表单 现在,在代码中: 在这里,MenuForm被加载为读取正确代码后必须可访问的表单。我打电话给frmWaiterKey让他出现 Priv

我正在开发一个应用程序,从串口通信端口读取数据。 简而言之,它的工作原理是这样的:当你在酒吧或餐馆工作时,在你可以在登记簿中输入一些东西之前,你必须扫描一种卡片。如果这张卡返回的数字正确,你可以输入一些东西

因此,必须有一个表单来监听串行端口,并检查是否有人扫描了一张卡,以及它是否是一张具有良好权限的卡

如果此人拥有良好的权利,则可以关闭该表单,并调用另一个表单

现在,在代码中:

在这里,MenuForm被加载为读取正确代码后必须可访问的表单。我打电话给frmWaiterKey让他出现

Private Sub frmMenu_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim oForm As frmWaiterKey = New frmWaiterKey()
    oForm.ShowDialog()
End Sub
frmWaiterKey类的代码:

Private Sub frmWaiterKey_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    nameArray = SerialPort.GetPortNames
    OpenComPort()
    AddHandler myComPort.DataReceived, SerialDataReceivedEventHandler1
End Sub

Sub OpenComPort()

    Try
        ' Get the selected COM port's name 
        ' from the combo box.
        If Not myComPort.IsOpen Then
            myComPort.PortName = _
            nameArray(0).ToString()
            ' Get the selected bit rate from the combo box.
            myComPort.BaudRate = CInt(9600)
            ' Set other port parameters.
            myComPort.Parity = Parity.None
            myComPort.DataBits = 8
            myComPort.StopBits = StopBits.One
            myComPort.Handshake = Handshake.None

            'myComPort.ReadTimeout = 3000
            'myComPort.WriteTimeout = 5000

            ' Open the port.
            myComPort.Open()

        End If

    Catch ex As InvalidOperationException
        MessageBox.Show(ex.Message)
    Catch ex As UnauthorizedAccessException
        MessageBox.Show(ex.Message)
    Catch ex As System.IO.IOException
        MessageBox.Show(ex.Message)
    End Try

End Sub
Sub CloseComPort()

    Using myComPort
        If (Not (myComPort Is Nothing)) Then
            ' The COM port exists.
            If myComPort.IsOpen Then
                ' Wait for the transmit buffer to empty.
                Do While (myComPort.BytesToWrite > 0)
                Loop
            End If
        End If
    End Using

End Sub

Private SerialDataReceivedEventHandler1 As New SerialDataReceivedEventHandler(AddressOf DataReceived)

' Specify the routine that runs when 
' a DataReceived event occurs at myComPort.

' This routine runs when data arrives at myComPort.

Friend Sub DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)
    Dim newReceivedData As String
    ' Get data from the COM port.
    newReceivedData = myComPort.ReadExisting
    newReceivedData = newReceivedData.Trim()
    MsgBox(newReceivedData)
    If newReceivedData.Equals("00150324294764") Then
        CloseComPort()
        Me.Close()
    End If

End Sub
我在最后一行得到一个错误:Me.Close 我明白了:我从frmMenu调用表单frmWaiterKey,但无法在这里关闭它。。。 但是我不知道如何解决这个问题


我希望有人能帮助我或告诉我我做错了什么。

首先,你需要做一个如下的方法:

Private Sub CloseMe()
    If Me.InvokeRequired Then
        Me.Invoke(New MethodInvoker(AddressOf CloseMe))
        Exit Sub
    End If
    Me.Close()
End Sub
If newReceivedData.Equals("00150324294764") Then
    CloseComPort()
    CloseMe()
End If
然后,通过调用该方法关闭表单,如下所示:

Private Sub CloseMe()
    If Me.InvokeRequired Then
        Me.Invoke(New MethodInvoker(AddressOf CloseMe))
        Exit Sub
    End If
    Me.Close()
End Sub
If newReceivedData.Equals("00150324294764") Then
    CloseComPort()
    CloseMe()
End If

之所以需要这样做,是因为WinForms中的所有UI活动都必须从同一线程执行。因为DataReceived方法是从另一个线程调用的,所以它必须返回UI线程才能关闭表单。如果您在UI线程以外的任何线程上,并且Invoke方法从UI线程调用给定方法,InvokeRequired属性将返回true。

首先,您需要创建如下方法:

Private Sub CloseMe()
    If Me.InvokeRequired Then
        Me.Invoke(New MethodInvoker(AddressOf CloseMe))
        Exit Sub
    End If
    Me.Close()
End Sub
If newReceivedData.Equals("00150324294764") Then
    CloseComPort()
    CloseMe()
End If
然后,通过调用该方法关闭表单,如下所示:

Private Sub CloseMe()
    If Me.InvokeRequired Then
        Me.Invoke(New MethodInvoker(AddressOf CloseMe))
        Exit Sub
    End If
    Me.Close()
End Sub
If newReceivedData.Equals("00150324294764") Then
    CloseComPort()
    CloseMe()
End If

之所以需要这样做,是因为WinForms中的所有UI活动都必须从同一线程执行。因为DataReceived方法是从另一个线程调用的,所以它必须返回UI线程才能关闭表单。如果您在UI线程以外的任何线程上,InvokeRequired属性将返回true,Invoke方法将从UI线程调用给定的方法。

它可以工作!我以前试过这个,但我把这些代码行放在frmMenu中。非常感谢你!它起作用了!我以前试过这个,但我把这些代码行放在frmMenu中。非常感谢你!