Is there a way to check if IEnumerable is available using a For Each loop?
Suppose I have an IEnumerable like List (TValue) and I want to keep track of if that list is available (to prevent problems with, say, adding to the list while it is iterating over on another thread); I can always write code like:
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 am talking about.)
My question is, is there a better / cleaner way to accomplish this check than by manually updating and accessing the boolean as above. I feel like there should be, but as far as I know there is no IEnumerable class with a built-in "I repeat myself" method. And writing a new class that implements IEnumerable and contains such a property seems overkill to me.
a source to share
Afaik. In VB.NET, you can use SyncLock
to place a lock around an object while accessing it to prevent concurrent work with other threads.
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
a source to share
It depends on what you are doing, if you are worried about multiple write access to the list Synclock
- this is the way to go.
If you are after throwing exceptions while listing, it is sometimes better to make a copy and list such as
For Each Num as Integer in SumOfPositives.ToArray()
...
Next Num
Obviously you can consider using and performance RAM, etc., but overall it works great and is pretty fast.
a source to share
VB.net will use the GetEnumerator function when appropriate, preferring to use the IEnumerable interface. Thus, it is possible to implement IEnumerable, but the call gives a method that implements IEnumerable.GetEnumerator some other name. Since most other routines that will enumerate something will use IEnumerable and not Get-Enuncher, but the fact that the GetEnumerator method is itself called suggests that it is used for every loop.
a source to share