我正在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()并注释掉接下来的两行,它应该在后台运行,但在'frmMain.ModView中的TreeNode的每行都'用户代码未处理ArgumentOutOfRangeException崩溃.Nodes(0).Nodes从ScanModules子底部的22行。异常详细信息是;
用户代码未处理System.ArgumentOutOfRangeException Message =“指定的参数超出有效值范围。参数名称:index” ParamName =“ index” Source =“ System.Windows.Forms” 堆栈跟踪: 在System.Windows.Forms.TreeNodeCollection.get_Item(Int32索引) 在C:\ BaartOLM.VBNET \ General.vb:第291行的BaartOLM.General.ScanModules()中 在BaartOLM.frmMain.BgdScan_DoWork(Object sender,DoWorkEventArgs e)在C:\ BaartOLM.VBNET \ main.vb:第631行 在System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e) 在System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object参数) InnerException:
我以前从未使用过backgroundworker,所以这对我来说是新的。谁能提出建议,为什么这段代码可以在后台运行,但不能在后台运行?
谢谢您的帮助,史蒂夫。