Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Why My Thread Safe Generic List Does Not Respect My Enumerator

0.00/5 (No votes)
23 May 2014 1  
ThreadSafe Generic List

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
           
            ' the collection works fine with this value

            'value = Me.InnerList.GetEnumerator()

        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

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here