如何将每个字典循环转换为并行的foreach循环

时间:2013-03-06 02:25:57

标签: vb.net foreach parallel-processing

如何将此代码转换为Parallel.ForEach (WorkingDict is a HybridDictionary)

我在下面提供了我的代码(请不要判断我的方法。这个工具是我第一次尝试上课,我开始相信我已经让它变得相当复杂和费力了。)< / p>

Dim Cntr As Integer = 0, Bool1 As Boolean = False
For Each Obj As Object In BusLoadDict.Keys
    Cntr = 0
    Bool = False
    bool1 = False
    For Each Obj2 As Object In PNodesDict.Keys
        For Each Obj1 As Object In DirectCast(PNodesDict.Item(Obj2.ToString), PNodeClass) _
            .PNodeDescriptionDictOfDicts.Keys
            If Obj1.ToString.Contains("forecast zone") Then
                If DirectCast(DirectCast(DirectCast(PNodesDict.Item(Obj2.ToString),  _
                            PNodeClass).PNodeDescriptionDictOfDicts, HybridDictionary).Item("forecast zone"),  _
                    HybridDictionary).Contains(BusLoadDict.Item(Obj.ToString)) Then
                    Bool = True
                    Cntr += 1
                    If Cntr = 2 Then GoTo 1
                End If
            End If
            If Obj1.ToString.Contains("aggregate") Then
                Bool1 = True
                If DirectCast(DirectCast(DirectCast(PNodesDict.Item(Obj2.ToString),  _
                            PNodeClass).PNodeDescriptionDictOfDicts, HybridDictionary).Item("aggregate"),  _
                    HybridDictionary).Contains(BusLoadDict.Item(Obj.ToString)) Then
                    Bool = True
                    Cntr += 1
                    If Cntr = 2 Then GoTo 1
                End If
            End If
        Next
    Next
1:          If Bool = False Then
    SBuilder.AppendLine("Bus PNode " & Obj.ToString & " was not mapped to the forecast zone pnodes.")
    End If
    If bool1 = False Then
        SBuilder.AppendLine("Bus PNode " & Obj.ToString & " was not mapped to the aggregate pnodes.")
    End If
Next

这是错误代码。

Error   1   Overload resolution failed because no accessible 'ForEach' can be called with these arguments:
    'Public Shared Function ForEach(Of TSource)(source As System.Collections.Concurrent.OrderablePartitioner(Of TSource), body As System.Action(Of TSource, System.Threading.Tasks.ParallelLoopState, Long)) As System.Threading.Tasks.ParallelLoopResult': Data type(s) of the type parameter(s) cannot be inferred from these arguments. Specifying the data type(s) explicitly might correct this error.
    'Public Shared Function ForEach(Of TSource)(source As System.Collections.Concurrent.Partitioner(Of TSource), body As System.Action(Of TSource, System.Threading.Tasks.ParallelLoopState)) As System.Threading.Tasks.ParallelLoopResult': Data type(s) of the type parameter(s) cannot be inferred from these arguments. Specifying the data type(s) explicitly might correct this error.
    'Public Shared Function ForEach(Of TSource)(source As System.Collections.Concurrent.Partitioner(Of TSource), body As System.Action(Of TSource)) As System.Threading.Tasks.ParallelLoopResult': Data type(s) of the type parameter(s) cannot be inferred from these arguments. Specifying the data type(s) explicitly might correct this error.
    'Public Shared Function ForEach(Of TSource)(source As System.Collections.Generic.IEnumerable(Of TSource), body As System.Action(Of TSource, System.Threading.Tasks.ParallelLoopState, Long)) As System.Threading.Tasks.ParallelLoopResult': Data type(s) of the type parameter(s) cannot be inferred from these arguments. Specifying the data type(s) explicitly might correct this error.
    'Public Shared Function ForEach(Of TSource)(source As System.Collections.Generic.IEnumerable(Of TSource), body As System.Action(Of TSource, System.Threading.Tasks.ParallelLoopState)) As System.Threading.Tasks.ParallelLoopResult': Data type(s) of the type parameter(s) cannot be inferred from these arguments. Specifying the data type(s) explicitly might correct this error.
    'Public Shared Function ForEach(Of TSource)(source As System.Collections.Generic.IEnumerable(Of TSource), body As System.Action(Of TSource)) As System.Threading.Tasks.ParallelLoopResult': Data type(s) of the type parameter(s) cannot be inferred from these arguments. Specifying the data type(s) explicitly might correct this error. C:\My Folder\Market Operations\VB.net\Market Validations Tool\Market Validations Tool\Market Operations Tool.vb 6361    9   Market Validations Tool

1 个答案:

答案 0 :(得分:2)

你可以这样做。

Dim WorkingDict As New HybridDictionary
WorkingDict.Add("k1", "v1")
WorkingDict.Add("k2", "v2")
Parallel.ForEach(WorkingDict.Cast(Of Object),
                 Sub(DictObject As KeyValuePair(Of String, String))
                     ' do something
                 End Sub)

您需要使用IEnumerable.Cast运算符,因为Parallel.Foreach only works with generic collectionsHybridDictionary是非通用集合。

但请记住,这是一个非常简单的[空]示例,更复杂的并行操作需要许多注意事项,例如锁定共享资源等。您可以始终考虑使用System.Collections.ConcurrentDictionary,它处理锁定共享资源,如果需要。 A SO post on this。例如:

Dim WorkingDict As New ConcurrentDictionary(Of String, String)
' ConcurrentDictionary has no Add operator, so to replicate it, use AddOrUpdate
' and just pass the same value whether it is being added or updating
WorkingDict.AddOrUpdate("key1", "value1", Function(key, oldvalue) "value1")
WorkingDict.AddOrUpdate("key2", "value2", Function(key, oldvalue) "value2")
Parallel.ForEach(WorkingDict,
                 Sub(DictObject as DictionaryEntry)
                     ' do something
                 End Sub)