.net 当在ForEach循环中获取属性时?

.net 当在ForEach循环中获取属性时?,.net,multithreading,locking,foreach,.net,Multithreading,Locking,Foreach,我有一个带锁的属性getter,如下所示: Public ReadOnly Property ActiveClientList() as List(Of TcpClient) Get SyncLock(m_activeClientListLock) Return m_activeClientList End SyncLock End Get End Property 当我执行ForEach循环时,何时获取属性?我的意思是,

我有一个带锁的属性getter,如下所示:

Public ReadOnly Property ActiveClientList() as List(Of TcpClient)
    Get
        SyncLock(m_activeClientListLock)
            Return m_activeClientList
        End SyncLock
    End Get
End Property
当我执行ForEach循环时,何时获取属性?我的意思是,在这个循环中,当列表被锁定时?第一次检查时?在每次迭代中?在整个环路

For Each client as TcpClient in Me.ActiveClientList

Next

提前谢谢

在上述场景中,当for循环首次初始化时,会获得一次锁。返回列表并释放锁,然后开始迭代。

Me.ActiveClientList将为您提供对m_ActiveClientList的引用,因此此引用将一次性获取(在循环启动和使用锁时),并在整个循环中使用。因此,这意味着,如果列表中的元素在循环过程中发生更改(通过其他线程),则不会受到保护

但是,如果您试图实现对列表的同步访问(例如,如果它是共享列表或其他内容),请查看以下链接:


您可以锁定
SyncRoot
以锁定对列表的访问。

您的锁定代码将只锁定return语句,而不会锁定其他语句。
不可能存在锁定多条语句的情况


每个循环的
将读取一次属性,然后调用
GetEnumerator

,因为每个
实际上都是语法糖。编译器将其扩展为:

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
如果这不是VB.NET(我是C#boy)的话,我会道歉


如您所见,对
ActiveClientList
的调用只发生一次,就在循环的开始处。

这是一个很好的解释。谢谢。你最后忘记了处理枚举数的
块。我们不要再为这个可怜的家伙操心了!如果他们真的想离开,确切地了解循环是如何扩展的,有比我的灰质更好的资源。