1

List(TValue) などの IEnumerable があり、このリストがアクセスされているかどうかを追跡したいとします (別のスレッドで反復されている間にリストに追加するなどの問題を防ぐため)。次のようなコードをいつでも書くことができます。

Dim List1 As New List(Of Integer)
Dim IteratingList1 As Boolean = False

' ... some code ... '

Private Function getSumOfPositivesFromList1() As Integer
    If IteratingList1 Then Return -1

    IteratingList1 = True

    Dim SumOfPositives As Integer = 0

    For Each x As Integer In List1
        If x > 0 Then SumOfPositives += x
    Next

    IteratingList1 = False

    Return SumOfPositives
End Function

(このコードは非常に恣意的なものですが、私が話していることを示しています。)

私の質問は、上記のようにブール値を手動で更新してアクセスするよりも、このチェックを実行するためのより良い/よりクリーンな方法があるかどうかです。あるに違いないと思いますが、私の知る限り、組み込みの「反復処理中」メソッドまたはプロパティを持つ IEnumerable クラスはありません。そして、IEnumerable を実装し、そのようなプロパティを含む新しいクラスを作成することは、やり過ぎのように思えます。

4

3 に答える 3

3

Afaik、VB.NET では、 を使用しSyncLockて、オブジェクトにアクセスしているときにオブジェクトの周りにロックを配置して、他のスレッドが同時にそのオブジェクトで作業するのを防ぐことができます。

Public Shared objStorageLock As New Object

Private Function getSumOfPositivesFromList1() As Integer

    Dim SumOfPositives As Integer = 0

    SyncLock objStorageLock 

    For Each x As Integer In List1
        If x > 0 Then SumOfPositives += x
    Next

    End SyncLock

    Return SumOfPositives
End Function
于 2009-05-19T13:32:15.600 に答える
1

VB.net は、IEnumerable インターフェイスを使用する代わりに、適切な関数が存在する場合は GetEnumerator 関数を使用します。したがって、IEnumerable を実装できますが、IEnumerable.GetEnumerator を実装するメソッドに別の名前を付けて呼び出します。何かを列挙する他のほとんどのルーチンは、ダックタイピング GetEnumerator ではなく IEnumerable を使用するため、GetEnumerator メソッド自体が呼び出されるという事実は、for-each ループで使用されていることを示唆しています。

于 2011-02-01T15:45:59.290 に答える
1

リストへの複数の書き込みアクセスが心配な場合は、何をするかによって異なりますSynclock

列挙中に例外を排除した後であれば、コピーを取得して列挙する方が良い場合があります。

For Each Num as Integer in SumOfPositives.ToArray()
...
Next Num

明らかに、RAM の使用量やパフォーマンスなどを考慮する必要があるかもしれませんが、一般的にこれは問題なく動作し、非常に高速です。

于 2009-05-19T13:37:42.810 に答える