首页 > 解决方案 > 作为后台工作程序运行时工作代码失败

问题描述

我正在我的 PC 上开发客户端应用程序。我有几个模块连接到我的网络。这些模块是我设计的用作服务器的板。我希望客户端每 15 秒对网络进行一次扫描,以查看是否有任何新服务器添加到网络中,如果有,请将它们记录到 MySQL 数据库中,并确定哪些服务器已经记录到数据库中在线的。数据库中离线的在树形视图中显示为红色,在线显示为绿色,因此如果电路板出现故障,我可以检查它是否出现故障或电缆损坏或其他原因关闭。

好的,这是执行扫描的子程序

Public Sub ScanModules()

    Dim Mdc As ADODB.Command
    Dim Sr As ADODB.Recordset

    Dim check As String
    Dim modsonline As Integer = 0
    Dim l, a, b As Integer
    Dim repdelay As Integer = 100
    Dim result As Integer = 0
    Dim myser As String
    Dim scantime As String = Date.Today.Date & " at " & TimeOfDay.ToString("h:mm:ss")
    Dim modtype As String
    Dim serno As String
    Dim ismod As Boolean
    If My.Computer.Network.IsAvailable Then
        ' get the ARP table and parse it to see all IP and MAC addresses currently registered
        Dim sCommand As String = "arp"
        Dim sArgs As String = "-a"
        Dim psi As System.Diagnostics.ProcessStartInfo = New System.Diagnostics.ProcessStartInfo(sCommand, sArgs)
        psi.UseShellExecute = False
        psi.RedirectStandardOutput = True
        psi.CreateNoWindow = True
        arptable = ""
        Dim proc As System.Diagnostics.Process = System.Diagnostics.Process.Start(psi)
        arptable = proc.StandardOutput.ReadToEnd

        l = Len(arptable)
        a = 90
        b = 112

        Mdc = New ADODB.Command
        Mdc.let_ActiveConnection(DBCon)
        Mdc.CommandType = ADODB.CommandTypeEnum.adCmdText
        Mdc.CommandText = "SELECT * from machine"
        Sr = Mdc.Execute
        nummacs = Sr.RecordCount

        ' look for Baart modules in the ARP table - MAC will start ea and be all decimal numbers
        Do While b < l
            myip = RTrim(Mid(arptable, a, 15))
            mymac = Mid(arptable, b, 17)
            If VB.Left(mymac, 2) = "ea" Then
                ismod = True
                check = Mid(mymac, 4, 2) & Mid(mymac, 7, 2) & Mid(mymac, 10, 2) & Mid(mymac, 13, 2) & Mid(mymac, 16, 2)
                For z = 1 To 10
                    If Asc(Mid(check, z, 1)) > 57 Then ismod = False
                Next
                If ismod Then
                    Cmd = New ADODB.Command
                    Mdc.let_ActiveConnection(DBCon)
                    Mdc.CommandType = ADODB.CommandTypeEnum.adCmdText
                    Mdc.CommandText = "SELECT * from modules WHERE macaddr = '" & mymac & "'"
                    Sr = Mdc.Execute
                    If Sr.RecordCount = 0 Then 'module is not in database, add it
                        EthMsg = ""
                        sendmsg("ENQ", myip)
                        If EthMsg = "ACK" Then ' if reply is not ACK then either not a Baart or not actually online
                            EthMsg = ""
                            modsonline = modsonline + 1
                            sendmsg("SER", myip)
                            serno = EthMsg
                            EthMsg = ""
                            sendmsg("TYP", myip)
                            modtype = EthMsg
                            EthMsg = ""
                            sendmsg("EOT", myip)
                            If EthMsg = "ACK" Then
                                Mdc.CommandText = "INSERT INTO modules (macaddr, serno, modtype, ipaddr, active, assigned) VALUES ('"
                                Mdc.CommandText = Mdc.CommandText & mymac & "','" & serno & "','" & modtype & "','" & myip & "', 1, 0 )"
                                Mdc.Execute()
                                Mdc.CommandText = "SELECT * from modules WHERE macaddr = '" & mymac & "'"
                                Sr = Mdc.Execute
                            End If
                        End If
                    Else
                        Mdc.CommandText = "UPDATE modules set ipaddr = '" & myip & "', active = '1' WHERE macaddr = '" & mymac & "'"
                        Sr = Mdc.Execute
                    End If

                End If
            End If
            a = a + 58
            b = b + 58
        Loop

        ' now update the module treeview showing which modules are online by pinging them
        Mdc.CommandText = "SELECT * from modules"
        Sr = Mdc.Execute

        If Sr.RecordCount > 0 Then
            Sr.MoveFirst()
            For a = 0 To Sr.RecordCount - 1
                myip = Trim(Sr.Fields.Item("ipaddr").Value)
                myser = Sr.Fields.Item("serno").Value
                If My.Computer.Network.Ping(myip, 100) Then
                    Mdc.CommandText = "UPDATE modules set active = '1', lastol = '" & scantime & "' WHERE ipaddr = '" & myip & "'"
                    Mdc.Execute()
                    For Each n As TreeNode In frmMain.ModView.Nodes(0).Nodes
                        If n.Text = myser Then
                            n.ImageIndex = 6
                            n.SelectedImageIndex = 6
                        End If
                    Next
                Else
                    Mdc.CommandText = "UPDATE modules set active = '0' WHERE ipaddr = '" & myip & "'"
                    Mdc.Execute()

                    For Each n As TreeNode In frmMain.ModView.Nodes(0).Nodes
                        If n.Text = myser Then
                            n.ImageIndex = 7
                            n.SelectedImageIndex = 7
                        End If
                    Next
                End If
                Sr.MoveNext()
            Next
        End If
    End If
End Sub

我的代码中也有这两个子

Private Sub ScanTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles ScanTimer.Tick
    'BgdScan.RunWorkerAsync()
    Call ScanModules()
    Application.DoEvents()
End Sub

Private Sub BgdScan_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BgdScan.DoWork
    Call ScanModules()
    Application.DoEvents()
End Sub

您将在 ScanTimer_Tick 子中看到我已将 BgdScan.RunWorkerAsync() 注释掉,因此它不会在后台运行,而且效果很好。如果我拔掉一块板子,它会在 15 秒内在树形视图上变成红色。如果我重新插入它,它会变成绿色。但是,如果我取消注释 BgdScan.RunWorkerAsync() 并注释掉接下来的两行,它应该在后台运行,但它会在 For 'Each n As TreeNode In frmMain.ModView .Nodes(0).Nodes' 从 ScanModules 子底部开始的 22 行。异常细节是;

System.ArgumentOutOfRangeException 未被用户代码处理 Message="指定的参数超出了有效值的范围。参数名称:索引" ParamName="index" Source="System.Windows.Forms" StackTrace:在 System.Windows.Forms。 C:\BaartOLM.VBNET\General.vb 中 BaartOLM.General.ScanModules() 处的 TreeNodeCollection.get_Item(Int32 索引):C:\BaartOLM.VBNET\ 中 BaartOLM.frmMain.BgdScan_DoWork(Object sender, DoWorkEventArgs e) 处的第 291 行main.vb:System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)处的第 631 行 System.ComponentModel.BackgroundWorker.WorkerThreadStart(对象参数)InnerException:

我以前从未使用过 backgroundworker,所以这对我来说是新的。谁能建议为什么这段代码可以在前台运行但不能在后台运行?

谢谢你的帮助,史蒂夫。

标签: vb.netbackgroundworker

解决方案


推荐阅读