2009-12-30 5 views
2

J'ai un getter de la propriété avec une serrure comme celui-ci:Lorsque la propriété est gérée dans une boucle ForEach?

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

Quand je fais une boucle foreach quand est la propriété getted? Je veux dire, dans cette boucle lorsque la liste est verrouillée? Au premier contrôle? À chaque itération? À la boucle entière?

For Each client as TcpClient in Me.ActiveClientList 

Next 

Merci d'avance!

Répondre

2

For Each est en réalité du sucre syntactique. Le compilateur se développe à ceci:

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 

Toutes mes excuses si ce n'est pas vrai VB.NET (je suis un garçon C#).

Comme vous pouvez le voir, l'appel à ActiveClientList se produit une fois, dès le début de la boucle.

+0

Très bonne explication. Merci. –

+1

Vous avez oublié le bloc 'Finally' pour disposer de l'énumérateur. – SLaks

+1

Ne va pas trop compliquer les choses pour le pauvre garçon! S'ils veulent vraiment partir et apprendre exactement comment les boucles sont développées, il y a de meilleures ressources que ma matière grise. –

2

Dans votre scénario ci-dessus, le verrou est obtenu une fois lorsque la boucle for est initialisée pour la première fois. La liste est renvoyée et le verrou est libéré, puis l'itération démarre.

2

Me.ActiveClientList vous donnera une référence à m_activeClientList, donc cette référence sera récupérée une seule fois (à l'initiation de la boucle et en utilisant le verrou) et utilisée tout au long de la boucle. Cela signifie donc que vous n'êtes pas protégé si des éléments de la liste changent (via un autre thread) pendant votre boucle.

Cependant, si ce que vous essayez d'atteindre un accès synchronisé à la liste (comme si elle est une liste partagée ou quelque chose), puis vérifier ce lien sur: How to synchronize the access to a List<T> used in ASP.NET?

Vous pouvez verrouiller le SyncRoot pour verrouiller l'accès à la liste.

2

Votre code de verrouillage verrouillera uniquement l'instruction return, et rien d'autre.
Il n'existe aucun scénario possible dans lequel vous verrouillerez plusieurs instructions. La boucle For Each lit la propriété une fois, puis appelle le GetEnumerator.

Questions connexes