Vb.net 从单独的线程更改TreeView节点的前景色
使用以下代码,我在mainformloadevent中用一个根节点和几个子节点填充一个树视图。使用按钮btnPing,我浏览节点并搜索级别为2的子节点。然后使用My.computer.network.ping查询这些节点,并根据结果将ChildNode的前景色涂成红色或绿色。整个作品都是同义词。然而,图形用户界面每次都让我僵住了Vb.net 从单独的线程更改TreeView节点的前景色,vb.net,multithreading,treeview,Vb.net,Multithreading,Treeview,使用以下代码,我在mainformloadevent中用一个根节点和几个子节点填充一个树视图。使用按钮btnPing,我浏览节点并搜索级别为2的子节点。然后使用My.computer.network.ping查询这些节点,并根据结果将ChildNode的前景色涂成红色或绿色。整个作品都是同义词。然而,图形用户界面每次都让我僵住了 '### TreeView Test Option Explicit On Option Strict On Public Partial Class Main
'### 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级的线程,然后等待反馈。最好的方法是什么
致意
凯一些想法
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
以下是另一种方法:
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
谢谢,但我有3个错误:任务未定义。你能帮我吗?@Kay你用的是什么版本的.Net?.Net 4我是using@Kay在代码的开头添加此导入System.Threading.TasksJust NOT,Ping类已经存在。使用PingCompleted事件更新您的UI。您正试图从无法工作的任务访问UI。在哪里?…我不是从任务访问UI。请在Using块中详细说明@dbasnett。我们已经从任务中返回,当我们到达这些行时,已经回到UI线程中@Dbasneti确实尝试了代码;它工作得很好,没有错误,而且我的UI响应良好。更改了代码,使其更清楚地显示发生了什么@德巴斯内特