1

List(of MyCustomObject) があります。このリストは TreeView の DataSource です。現在、収集されたすべてのオブジェクトは定期的に Rising Timer1_Timer イベントで更新する必要があります。更新するには、Parallel.ForEachを使用しています。これはテスト アプリでは正常に機能しますが、最終的なアプリケーションは計算用のコードを追加した後にハングし、ランダムな数の relult が存在しない可能性があります。それを修正するのを手伝ってください。

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
4

1 に答える 1

0

これはテスト アプリでは正常に機能しますが、最終的なアプリケーションは計算用のコードを追加した後にハングし、乱数の結果が存在しない可能性があります。

これは、表示されていないコードに問題がある可能性があることを意味していると思われます。

最も可能性の高い候補は、実際の zupdateメソッドのコードが、デッドロックしているある種の共有リソースにアクセスしていることです。

于 2013-02-01T04:33:59.347 に答える