2017-06-11 65 views
0

使用以下代碼,我在MainForm LoadEvent中填充具有根節點和多個子節點的Treeview。使用按鈕btnPing,我瀏覽節點並搜索級別爲2的子節點。然後使用My.computer.network.ping查詢這些節點,並根據結果紅色或綠色對ChildNode的ForeColor進行着色。整個作品是同義詞。但是,GUI每次都凍結我。從單獨的線程更改TreeView節點的前景色

'### TreeView Test 
Option Explicit On 
Option Strict On 
Public Partial Class MainForm 
    Public Sub New() 
     Me.InitializeComponent() 
    End Sub 

'### Hauptprogramm wird geladen ### 
    Sub MainFormLoad(sender As Object, e As EventArgs) 
'Treeview befüllen 
With treeView1 
.Nodes.Add("Test1") 
.Nodes(0).Nodes.Add("Test1_a") 
.Nodes(0).Nodes.Add("Test1_b") 
.Nodes(0).Nodes.Add("Test1_c") 
.Nodes(0).Nodes(0).Nodes.Add("10.23.59.1") 
.Nodes(0).Nodes(1).Nodes.Add("10.23.59.90") 
.Nodes(0).Nodes(1).Nodes.Add("10.23.59.90") 
.Nodes(0).Nodes(2).Nodes.Add("10.23.59.10") 
.Nodes(0).Nodes(2).Nodes.Add("10.23.59.11") 
.Nodes(0).Nodes(2).Nodes.Add("10.23.59.12") 
.Nodes(0).Nodes(2).Nodes.Add("10.23.59.13") 
.Nodes(0).Nodes(2).Nodes.Add("10.23.59.14") 
End With 
'Treeview aufklappen 
treeView1.ExpandAll 
End Sub 

'### Sub zum rekursiven durchsuchen der Nodes ### 
    Private Sub RecurseNodes(ByVal col As TreeNodeCollection) 
     For Each tn As TreeNode In col    
     If tn.Level = 2 Then 
      Try 
      If My.Computer.Network.Ping(tn.Text) Then 
       tn.ForeColor = Color.Green 
       tn.StateImageIndex= 4 
      Else  
       tn.ForeColor = Color.Red 
       tn.StateImageIndex=5 
      End If 
      Catch ex As Exception 
       tn.ForeColor = Color.Red 
       tn.StateImageIndex=5 
      End Try 
     End If 

     If tn.Nodes.Count > 0 Then 
      RecurseNodes(tn.Nodes) 
     End If 
     Next tn 
    End Sub 

'### Button zum starten der rekursiven Suche ### 
    Sub BtnPingClick(sender As Object, e As EventArgs) 
     'Treeview rekursiv durchsuchen 
     RecurseNodes(treeView1.Nodes) 
    End Sub 
End Class 

現在我想轉換整個,以便Ping在一個單獨的線程中運行。現在我對這個過程只有一個理解問題。我可以用參數傳輸啓動一個線程嗎?然後,我會遍歷列表,並從每個具有2級線程的節點開始,等待反饋。最好的方法將如何?

問候 凱

+0

只是不,平安類已經[知道如何做到這一點] (https://msdn.microsoft.com/en-us/library/xya3e0zf(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1)。使用PingCompleted事件更新您的用戶界面。 –

回答

0

一些想法......

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
    Dim t As Task = Task.Run(Sub() 
           RecurseNodes(TreeView1.Nodes(0)) 
          End Sub) 
End Sub 

Private Sub RecurseNodes(ByVal col As TreeNode) 
    For Each tn As TreeNode In col.Nodes 
     If tn.Level < 2 AndAlso tn.Nodes.Count > 0 Then 
      RecurseNodes(tn) 
     ElseIf tn.Level = 2 Then 
      Dim tp As Task 
      tp = Task.Run(Sub() 
           Dim c As Color 
           Dim idx As Integer 
           Try 
            If My.Computer.Network.Ping(tn.Text) Then 
             c = Color.Green 
             idx = 4 
            Else 
             c = Color.Red 
             idx = 5 
            End If 
           Catch ex As Exception 
            c = Color.Red 
            idx = 5 
           End Try 
           Me.Invoke(Sub() 
              tn.ForeColor = c 
              tn.StateImageIndex = idx 
             End Sub) 
          End Sub) 
     End If 
    Next tn 
End Sub 
+0

謝謝,但我得到了3個錯誤:任務沒有定義。你能幫助我嗎? – Kay

+0

@Kay您使用的是什麼版本的.Net? – dbasnett

+0

.net 4我正在使用 – Kay

1

這裏的另一種方法:

Sub BtnPingClick(sender As Object, e As EventArgs) 
    'Treeview rekursiv durchsuchen 
    RecurseNodes(TreeView1.Nodes) 
End Sub 

Private Async Sub RecurseNodes(ByVal col As TreeNodeCollection) 
    For Each tn As TreeNode In col 
     If tn.Level = 2 Then 
      Dim T As Task(Of Boolean) = Ping(tn.Text) 
      Await T 
      tn.ForeColor = If(T.Result, Color.Green, Color.Red) 
      tn.StateImageIndex = If(T.Result, 4, 5) 
     ElseIf tn.Nodes.Count > 0 Then 
      RecurseNodes(tn.Nodes) 
     End If 
    Next tn 
End Sub 

Private Function Ping(ByVal ip As String) As Task(Of Boolean) 
    Return Task.Factory.StartNew(Of Boolean)(
     Function() As Boolean 
      Try 
       Return My.Computer.Network.Ping(ip) 
      Catch ex As Exception 
       Return False 
      End Try 
     End Function) 
End Function 
+0

您正嘗試從不起作用的任務訪問UI。 – dbasnett

+0

哪裏?...我不從任務訪問UI。請詳細說明@dbasnett –

+0

在Using塊中。 – dbasnett