Introduction
Enumerating through a collection is not thread safe, is it real? This question is knocking my head since I saw this subject in MSDN and subsequently more questions & ideas start in my mind. The
real question was, why shall we use thread safe collection? According to
Microsoft, the answer is simple, it is for better and faster
performance, however my understanding is also simple; to implement thread safe with a collection, all property and
methods within the generic class shall be written using SyncLock, hope
I'm correct.
But, while testing the collection, I noticed that no values are returned by the collection when using For Each
statement.
Below the GetEnumerator
method looks like:
Public Function GetEnumerator() As IEnumerator(Of T) Implements IEnumerable(Of T).GetEnumerator
Dim value As IEnumerator(Of T) = CType(Nothing, IEnumerator(Of T))
SyncLock Me._lock
value = New RiverNileListEnumerator(Me)
End SyncLock
Return value
End Function
Testing of the Collections looks like:
Private ColorList As RiverNileThreadSafeList(Of KnownColor) =
New RiverNileThreadSafeList(Of KnownColor)() From {KnownColor.ActiveCaption,
KnownColor.Aqua, KnownColor.YellowGreen}
For Each clr As KnownColor In ColorList
ListBox2.Items.Add(clr)
Next
Then I wrote the GetEnumerator
method like below and WOW....... collection works fine:
Public Function GetEnumerator() As IEnumerator(Of T) Implements IEnumerable(Of T).GetEnumerator
Dim value As IEnumerator(Of T) = CType(Nothing, IEnumerator(Of T))
SyncLock Me._lock
End SyncLock
Return value
End Function
I was wondering why my Thread Safe Generic List is not Respect my Enumerator? and return No Values. Then after searching & reading and to make my collection work fine, I shall write the code like this:
Private ColorList As RiverNileThreadSafeList(Of KnownColor) =
New RiverNileThreadSafeList(Of KnownColor)() From {KnownColor.ActiveCaption,
KnownColor.Aqua, KnownColor.YellowGreen}
For Each clr As KnownColor In ColorList.ToArray()
ListBox2.Items.Add(clr)
Next
Seems that IList
does not support lock and to write the code properly, I have to implement ICollection
instead of IList
to remove out the lock in the Add
method.
Using the Code
Download the source code and use it at your convenience or you may use as per the below code sample:
Private ColorList As RiverNileThreadSafeList(Of KnownColor) =
New RiverNileThreadSafeList(Of KnownColor)() From {KnownColor.ActiveCaption,
KnownColor.Aqua, KnownColor.YellowGreen}
For Each clr As KnownColor In ColorList.ToArray()
ListBox2.Items.Add(clr)
Next
Hope the code will be helpful for somebody and please, your comments will be very helpful, thanks!
History
- May 23rd 2014: Initial release