多线程IP地址ping导致应用程序崩溃

时间:2015-07-22 16:14:52

标签: vb.net multithreading ping

男孩,如果你找不到可靠的来源,那么学习新东西可能会非常令人头痛。我一直在以线性方式设计应用程序已有一段时间了,并希望采用更强大的方法。我一直在阅读线程,也许已经达到了比我应该更大的水平。但是,当应用程序需要它时,通常会逐步升级,并且没有比现在更好的时间来学习新的东西。

我的程序旨在做一些看似相当简单的事情,但在平稳的跑步庄园中创造起来非常困难。原始设计创建了它希望ping的网络上每个设备的对象,在我的真实世界环境中它们是Kindles。目标是通过Pining他们确保他们仍然连接到网络。我使用For LoopObj ArrayTimer上执行此设置。这会产生意外结果,导致ListViewListView1.Items.Clear之后闪烁并缓慢加载。我进化为更新List Items而不是清除它们,闪烁仍然存在。

我认为这是由于数组和ping的过程缓慢,所以我开始寻找解决方案并遇到Multi-Threading。我已经知道了一段时间,但尚未深入研究这种做法。我的程序似乎需要更快的速度和更平稳的操作,所以我抓了它。完整形式的下面的代码是结果,但它崩溃并抛出错误。很明显,我并没有按照预期使用线程。在更简单的功能中使用它工作正常,我觉得我有把握。那就是如果我希望我的程序毫无意义地运行计数器。

我不知道在完成这项任务的步骤中接下来要做什么,并且我想把几种不同的方法组合成一个死的程序。我真的可以使用一些帮助重新回到正轨。欢迎所有评论,并感谢您查看我的代码。

  

Form1代码

Public Class Form1

'Obj Array
Public Shared objDevice As New List(Of kDevice)
'Thread Array for each Obj
Public Shared thread() As System.Threading.Thread

Private Sub ipRefresh(objID, itemPos)

    Dim objDev As kDevice = objID

    If My.Computer.Network.Ping(objDev.kIP) Then
        objDev.kStatus = "Online"
        objDev.kPings = 0

    Else
        objDev.kPings += 1
    End If

    If objDev.kPings >= 8 Then
        objDev.kStatus = "Offline"
        objDev.kPings = 0
        ListView1.Items(itemPos).BackColor = Color.Red
    End If

    Dim str(4) As String
    Dim itm As ListViewItem
    str(0) = objDev.kName
    str(1) = objDev.kIP
    str(2) = objDev.kStatus
    str(3) = objDev.kPings
    itm = New ListViewItem(str)
    ListView1.Items(itemPos) = itm

End Sub

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    Me.CheckForIllegalCrossThreadCalls = False

    ' Adding ListView Columns
    ListView1.Columns.Add("Device", 100, HorizontalAlignment.Left)
    ListView1.Columns.Add("IP Address", 150, HorizontalAlignment.Left)
    ListView1.Columns.Add("Status", 60, HorizontalAlignment.Left)
    ListView1.Columns.Add("Pings", 60, HorizontalAlignment.Left)

    Dim ipList As New List(Of String)
    Dim nameList As New List(Of String)

    Using MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser("kDevices.csv")
        MyReader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
        MyReader.Delimiters = New String() {","}
        Dim currentRow As String()
        Dim rowP As Integer = 1
        While Not MyReader.EndOfData
            Try
                currentRow = MyReader.ReadFields()
                Dim cellP As Integer = 0
                Dim nTemp As String = ""

                For Each currentField As String In currentRow

                    Select Case cellP

                        Case 0
                            nameList.Add(currentField.Replace("""", ""))
                        Case 1
                            ipList.Add(currentField.Replace("""", ""))

                    End Select
                    cellP += 1

                Next
            Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
                MsgBox("Line " & ex.Message & " is invalid.  Skipping")
            End Try
            rowP += 1
        End While
    End Using

    Dim nameLAR As String() = nameList.ToArray
    Dim ipLAR As String() = ipList.ToArray

    ReDim Preserve thread(nameLAR.Length)

    For i As Integer = 0 To nameLAR.Length - 1

        Dim newDevice As New kDevice
        Dim objNum = i

        objDevice.Add(newDevice)

        newDevice.kName = nameLAR(i)
        newDevice.kIP = ipLAR(i)

        If My.Computer.Network.Ping(newDevice.kIP) Then
            newDevice.kStatus = "Online"
        Else
            newDevice.kStatus = "Loading"
        End If

        Dim str(4) As String
        Dim itm As ListViewItem
        str(0) = newDevice.kName
        str(1) = newDevice.kIP
        str(2) = newDevice.kStatus
        str(3) = newDevice.kPings
        itm = New ListViewItem(str)
        If newDevice.kStatus = "Loading" Then
            itm.BackColor = Color.Yellow
        End If
        ListView1.Items.Add(itm)

        thread(objNum) = New System.Threading.Thread(Sub() Me.ipRefresh(objDevice(objNum), objNum))

    Next

End Sub

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick

    For i As Integer = 0 To objDevice.Count - 1

        thread(i).Start()

    Next

End Sub

End Class
  

kDevice Class

Public Class kDevice

Private strkName As String
Private strkIP As String
Private strkStatus As String
Private strkLastStatus As String
Private strkPings As Integer = 0

Public Property kName As String

    Get
        Return strkName
    End Get

    Set(value As String)
        strkName = value
    End Set

End Property

Public Property kIP As String

    Get
        Return strkIP
    End Get

    Set(value As String)
        strkIP = value
    End Set

End Property

Public Property kStatus As String

    Get
        Return strkStatus
    End Get

    Set(value As String)
        strkStatus = value
    End Set

End Property

Public Property kPings As Integer

    Get
        Return strkPings
    End Get

    Set(value As Integer)
        strkPings = value
    End Set

End Property

End Class
  

我的代码第32行的错误/崩溃,当它试图将更新传递给ListView项时

An unhandled exception of type 'System.ArgumentException'
occurred in Microsoft.VisualBasic.dll

Additional information: InvalidArgument=Value of '18'
is not valid for 'index'.

An unhandled exception of type 'System.NullReferenceException' 
occurred in Microsoft.VisualBasic.dll

Additional information: Object reference not set to an instance
of an object.

如果我的代码没有意义,或者至少知道我想要做什么,请告诉我,我会解释哪些部分不清楚。再次感谢您查看我的问题。

1 个答案:

答案 0 :(得分:1)

我注意到一个可能的问题:

Dim str(4) As String
    Dim itm As ListViewItem
    str(0) = newDevice.kName
    str(1) = newDevice.kIP
    str(2) = newDevice.kStatus
    str(3) = newDevice.kPings
    itm = New ListViewItem(str)
    If newDevice.kStatus = "Loading" Then
        itm.BackColor = Color.Yellow
    End If
    ListView1.Items.Add(itm)

在这里,你声明str(4)将是5个可能的索引(记住它从零开始),你应该有4(str(3))。我不认为这是整个问题,但只是一点点你应该修复。您也可能希望在不设置

的情况下查看更新列表视图的其他方法
Me.CheckForIllegalCrossThreadCalls = False

这是一个很棒的指南,在我完成第一个多线程应用程序时帮助了我:http://checktechno.blogspot.com/2012/11/multi-thread-for-newbies.html