views:

57

answers:

4

Hello,

I have a property getter with a lock like this one:

Public ReadOnly Property ActiveClientList() as List(Of TcpClient)
    Get
        SyncLock(m_activeClientListLock)
            Return m_activeClientList
        End SyncLock
    End Get
End Property

When I do a ForEach loop when is the property getted? I mean, in this loop when the list is locked? At the first check? On each iteration? At the whole loop?

For Each client as TcpClient in Me.ActiveClientList

Next

Thanks in advance!

+2  A: 

In your above scenario, the lock is obtained once when the for loop is first initialized. The list is returned and the lock is released, and then iteration starts.

Aviad P.
+2  A: 

Me.ActiveClientList will give you a reference to the m_activeClientList, so this reference will be fetched a single time (at loop initiation and using the lock) and used throughout the loop. So this means that you aren't protected if elements of the list change (via some other thread) during your loop.

However, if what you are trying to achieve is synchronized access to the list (like if it's a shared list or something), then check this link out: http://stackoverflow.com/questions/186527/how-to-synchronize-the-access-to-a-listt-used-in-asp-net

You can lock the SyncRoot to lock access to the list.

dcp
+2  A: 

Your lock code will only lock the return statement, and nothing else.
There is no possible scenario in which you'll lock for more than one statement.

the For Each loop will read the property once, then call GetEnumerator.

SLaks
+2  A: 

For Each is actually syntactic sugar. The compiler expands it to this:

Dim enumerator As IEnumerator(Of TcpClient)

enumerator = Me.ActiveClientList.GetEnumerator()

While enumerator.GetNext()

    Dim client As TcpClient
    client = enumerator.Current

    'Loop body inserted here.'

End While

Apologies if this isn't true VB.NET (I'm a C# boy).

As you can see, the call to ActiveClientList happens once, right at the start of the loop.

Programming Hero
Really nice explanation. Thanks.
SoMoS
You forgot the `Finally` block to dispose the enumerator.
SLaks
Let's not go over-complicating things for the poor chap! If they really want to go away and learn exactly how loops are expanded there are better resources than my grey-matter.
Programming Hero