2

XmlNodeList 内のノードを反復処理し、ノード名に応じてノードごとに異なるオブジェクトを作成し、それを印刷用のリストに追加するコードがあります。

For Each node as XmlNode In nodeList
    Select Case node.Name.ToUpper()
        Case "SHAPE"
            _items.Add(New ShapeTemplate(node, Me))
        Case "TEXTBLOCK"
            _items.Add(New TextblockTemplate(node, Me))
    End Select
Next

このコードは正常に動作しますが、ShapeTemplate コンストラクターと TextblockTemplate コンストラクターによって行われる必要があるすべての作業のため、非常に遅くなります。オブジェクトが _items に追加される順序は問題ではないため、高速化する良い方法は parallel.ForEach ループを使用することだと考えました。問題は、XmlNodeList が非ジェネリック コレクションであるため、parallel.ForEach で使用できないことです。XmlNodeList を List(Of XmlNode) に変換する方法を探していましたが、うまくいきませんでした。私が見続ける答えは

Dim nodes as New List(Of xmlNode)(nodeList.Cast(Of xmlNode)())

しかし、試してみると、「Cast」は XmlNodeList のメンバーではないというエラーが表示されます。

私もこのようにTryCastを使ってみました

Dim nodes as List(Of XmlNode) = TryCast(CObj(nodeList), List(Of XmlNode))

ただし、オブジェクトをキャストできないため、ノードは Nothing になります。

parallel.ForEach ループで XmlNodeList を使用する方法を知っている人はいますか?

編集:できれば、変換にループを使用しないようにしています

4

2 に答える 2

1

の代わりにParallel LINQを使用できますParallel.ForEach。これは、この種の変換により自然に適合するようです。これは通常の LINQ クエリと同じように見えますが、.AsParallel()追加されています。

Imports System.Linq

' _items will not be in same order as nodes in nodeList.
' Add .AsOrdered() after .AsParallel() to maintain order, if needed.
_items = (
    From node In nodeList.Cast(Of XmlNode)().AsParallel()
    Select item = CreateTemplate(node)
    Where item IsNot Nothing
).ToList()

Function CreateTemplate(node As XmlNode) As ITemplate ' interface or base class for your types
    Dim item As ITemplate
    Select Case node.Name.ToUpper()
        Case "SHAPE"
            item = New ShapeTemplate(node, Me)
        Case "TEXTBLOCK"
            item = New TextblockTemplate(node, Me)
        Case Else
            item = Nothing
    End Select
    Return item
End Function
于 2016-12-21T21:52:08.870 に答える