views:

102

answers:

2

Suppose I have an IEnumerable such as a List(TValue) and I want to keep track of whether this list is being accessed (to prevent issues with, say, adding to the list while it is being iterated over on a different thread); I can always write code such as the following:

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

(I realize this code is very arbitrary, but it illustrates what I'm talking about.)

My question is whether there's a better/cleaner way to perform this check than by manually updating and accessing a Boolean, as above. I feel like there must be, but, to my knowledge, there isn't any IEnumerable class with a built-in "I am being iterated over" method or property. And writing a new class that implements IEnumerable and contains such a property seems like overkill to me.

+3  A: 

Afaik, In VB.NET you can use the SyncLock to place a lock around an object while accessing it, to prevent other threads from simultaneously working on it.

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
Eoin Campbell
Thanks! I was not familiar with SyncLock before. Now just out of curiosity, in this scenario, why would I create this new objStorageLock Object rather than simply writing "SyncLock List1 ... End SyncLock"?
Dan Tao
Never mind; I found the answer to my own question on MSDN: "You cannot change the value of lockobject while executing a SyncLock block. The mechanism requires that the lock object remain unchanged."
Dan Tao
+1  A: 

It depends on what you doing, if you are worried about multiple write access to the list Synclock is the way to go.

If you are after eliminating exceptions during the enumeration then it's sometimes better to do get a copy and enumerate that such as

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

Obviously you might want to consider your RAM usage and performance etc. etc. but generally this works fine and quite fast.

dr. evil