Есть ли способ проверить доступ к IEnumerable с помощью цикла For Each? - PullRequest
1 голос
/ 19 мая 2009

Предположим, у меня есть IEnumerable, например List (TValue), и я хочу отслеживать доступ к этому списку (чтобы избежать проблем, скажем, с добавлением в список, пока он повторяется в другом потоке ); Я всегда могу написать такой код:

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 и содержит такое свойство, кажется мне излишним.

Ответы [ 3 ]

3 голосов
/ 19 мая 2009

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
1 голос
/ 01 февраля 2011

VB.net будет использовать функцию GetEnumerator, если подходящая существует, вместо использования интерфейса IEnumerable. Таким образом, можно реализовать IEnumerable, но при вызове дать методу, реализующему IEnumerable.GetEnumerator, другое имя. Поскольку большинство других подпрограмм, которые будут перечислять что-либо, будут использовать IEnumerable вместо GetEnumerator с типизацией утки, тот факт, что сам метод GetEnumerator вызывается, предполагает, что он используется циклом for-each.

1 голос
/ 19 мая 2009

Это зависит от того, что вы делаете, если вас беспокоит множественный доступ для записи в список Synclock - это путь.

Если вы исключаете исключения во время перечисления, то иногда лучше получить копию и перечислить ее, например

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

Очевидно, что вы, возможно, захотите рассмотреть использование ОЗУ, производительность и т. Д. И т. Д., Но в целом это работает нормально и довольно быстро.

...