我有一个 List(MyCustomObject)。此List是TreeView的DataSource。 现在,必须在periodicaly Rising Timer1_Timer事件上更新所有收集的对象。要更新我正在使用 Parallel.ForEach 。这在测试应用程序中工作正常,但最终应用程序在添加计算代码后会挂起,并且可能缺少随机的重复数。请帮忙解决。
Imports System.Threading.Tasks
Imports Telerik.WinControls.UI
Imports System.ComponentModel
Imports System.Threading
Imports Accessibility
Public Class Form1
Dim WithEvents bw As New BackgroundWorker
Private Sub Button6_Click(sender As System.Object, e As System.EventArgs) Handles Button6.Click
Upadte(rt.Nodes.Cast(Of RadTreeNode)())
End Sub
Private Shared Sub Upadte(Of T)(source As IEnumerable(Of T))
Parallel.ForEach(source, New ParallelOptions With {.TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext, .MaxDegreeOfParallelism = 5}, AddressOf zUpdate)
End Sub
' Following fragment is a simple example. Real code is more difficult. It includes Network requests, WQL queries e.t.c.
' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Private Shared Sub zUpdate(Of T)(node As T)
Dim item = TryCast(node, RadTreeNode)
If item Is Nothing Then
Return
End If
Dim n_node As New RadTreeNode("_" & item.Name)
n_node.Nodes.Add("Hardware")
Dim tf As Form = Control.FromHandle(Form1.Handle)
tf.BeginInvoke(New Action(Function() InlineAssignHelper(item, n_node)))
End Sub
' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Private Shared Function InlineAssignHelper(ByRef target As RadTreeNode, ByVal value As RadTreeNode) As RadTreeNode
target.Nodes.Add(value.Clone)
Return target
End Function
End Class
创造理念!我会检查一下。顺便说一下,完整代码中没有任何秘密。它只是第一个例子。这是完整的子zUpdate的副本,没有一些典型的查询,在STA中正常工作:
Private Shared Sub zUpdate(Of T)(anode As T)
Dim searcher As New ManagementObjectSearcher
Dim tt_node As RadTreeNode = TryCast(anode, RadTreeNode)
If tt_node Is Nothing Then
Return
End If
Dim t_node As String = tt_node.Name
Dim n_node As New RadTreeNode With {.Name = "_" & t_node, .Text = "_" & t_node}
Dim opt As New ConnectionOptions
opt.Authentication = AuthenticationLevel.PacketPrivacy
opt.EnablePrivileges = True
opt.Impersonation = ImpersonationLevel.Impersonate
opt.Username = CredentialCache.DefaultNetworkCredentials.UserName
opt.Password = CredentialCache.DefaultNetworkCredentials.Password
opt.Authority = "ntlmdomain:" & CredentialCache.DefaultNetworkCredentials.Domain
Dim scope As New ManagementScope("\\" & t_node & "\ROOT\CIMV2", opt)
Dim query As New ObjectQuery
If My.Computer.Network.Ping(t_node, 10) = False Then
Return
GoTo 1
End If
scope.Connect()
If Not scope.IsConnected Then
Return
GoTo 1
End If
'Summary
query.QueryString = "SELECT * FROM Win32_ComputerSystem"
searcher.Scope = scope
searcher.Query = query
n_node.Nodes.Add("Summary")
For Each queryobj As ManagementObject In searcher.Get
With n_node.Nodes("Summary")
.Nodes.Add("Name", "Name:" & queryobj("Name"), 6)
.Nodes.Add("Domain", "Domain:" & queryobj("Domain"), 6)
.Nodes.Add("Manufacturer", "Manufacturer:" & queryobj("Manufacturer"), 6)
.Nodes.Add("Model", "Model:" & queryobj("Model"), 6)
.Nodes.Add("NumberOfLogicalProcessors", "NumberOfLogicalProcessors:" & queryobj("NumberOfLogicalProcessors").ToString, 6)
.Nodes.Add("NumberOfProcessors", "NumberOfProcessors:" & queryobj("NumberOfProcessors").ToString, 6)
.Nodes.Add("TotalPhysicalMemory", "TotalPhysicalMemory:" & queryobj("TotalPhysicalMemory").ToString, 6)
.Nodes.Add("UserName", "UserName:" & queryobj("UserName"), 6)
.Nodes.Add("Workgroup", "Workgroup:" & queryobj("Workgroup"), 6)
End With
Next
'LogicalDisk
query.QueryString = "SELECT * FROM Win32_LogicalDisk"
searcher.Query = query
n_node.Nodes.Add("Hardware")
With n_node.Nodes("Hardware")
.Nodes.Add("LogicalDisks")
With .Nodes("LogicalDisks")
For Each queryobj As ManagementObject In searcher.Get
.Nodes.Add("Name", "Name" & ": " & queryobj("Name"), 6)
With .Nodes("Name")
.Nodes.Add("Description", "Description: " & queryobj("Description"), 6)
.Nodes.Add("DriveType", "DriveType: " & queryobj("DriveType"), 6)
.Nodes.Add("Size", "Size: " & queryobj("Size").ToString, 6)
.Nodes.Add("FreeSpace", "FreeSpace: " & queryobj("FreeSpace"), 6)
.Nodes.Add("VolumeName", "VolumeName: " & queryobj("VolumeName"), 6)
.Nodes.Add("VolumeSerialNumber", "VolumeSerialNumber: " & queryobj("VolumeSerialNumber"), 6)
End With
Next
End With
'network adapters
query.QueryString = "SELECT * FROM Win32_NetworkAdapterConfiguration"
searcher.Query = query
.Nodes.Add("NetworkAdapters")
With .Nodes("NetworkAdapters")
For Each queryobj As ManagementObject In searcher.Get
.Nodes.Add(CStr(queryobj("Description")))
With .Nodes(CStr(queryobj("Description")))
.Nodes.Add("DHCPServer", "DHCPServer: " & queryobj("DHCPServer"), 6)
.Nodes.Add("DNSDomain", "DNSDomain: " & queryobj("DNSDomain"), 6)
.Nodes.Add("DNSHostName", "DNSHostName: " & queryobj("DNSHostName"), 6)
.Nodes.Add("MACAddress", "MACAddress: " & queryobj("MACAddress"), 6)
.Nodes.Add("SettingID", "SettingID: " & queryobj("SettingID"), 6)
End With
Next
End With
End With
'software
query.QueryString = "SELECT * FROM Win32_Product"
searcher.Query = query
n_node.Nodes.Add("Software")
With n_node.Nodes("Software")
For Each queryobj As ManagementObject In searcher.Get
.Nodes.Add(queryobj("Name"))
With .Nodes(queryobj("Name"))
.Nodes.Add("InstallDate", "InstallDate: " & queryobj("InstallDate"), 6)
.Nodes.Add("IdentifyingNumber", "IdentifyingNumber: " & queryobj("IdentifyingNumber"), 6)
End With
Next
End With
Dim tf As Form = Control.FromHandle(Form2.Handle)
tf.BeginInvoke(New Action(Function() InlineAssignHelper(tt_node, n_node)))
1:
If Not searcher Is Nothing Then
searcher.Dispose()
scope = Nothing
End If
End Sub
Private Shared Function InlineAssignHelper(ByRef target As RadTreeNode, ByVal value1 As RadTreeNode) As RadTreeNode
Dim t_str As String = Now.Date.ToString & Now.TimeOfDay.ToString
target.Nodes.Add(t_str)
target.Nodes(t_str).Nodes.Add(value1.Clone)
Return target
End Function
答案 0 :(得分:0)
这在测试应用程序中运行良好,但最终应用程序在添加后挂起 计算代码和随机数结果可能不存在。
我怀疑这意味着您的问题可能存在于您未向我们展示的代码中。
最有可能的候选者是真正的 zupdate
方法中的代码正在访问某种死锁的共享资源。