vb.net - 作为后台工作程序运行时工作代码失败
问题描述
我正在我的 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,所以这对我来说是新的。谁能建议为什么这段代码可以在前台运行但不能在后台运行?
谢谢你的帮助,史蒂夫。
解决方案
推荐阅读
- sql - 如何使用存储过程删除雪花中多余的反斜杠(/)?
- pine-script - 松树脚本错误 - 使用了“系列字符串”类型的参数,但应使用“常量字符串”
- r - 如何在R中的列表中找到最大值的位置?
- python - 这个函数有什么作用?我收到一个 AttributeError
- reactjs - 如何用函数组件解决 React 中的不受控组件问题?
- php - 如何在 url 中隐藏用户 ID
- python - 尽管我的 python 脚本失败了,但 Gitlab 管道总是通过
- javascript - 从获取的数据中动态创建反应组件
- linux-device-driver - 在设备树中,节点的中断输出单元大小为 1,但其中断父节点似乎有 #interrupt-cells = 3。为什么?
- google-sheets - 表格:查找范围内第一次和最后一次出现的值