.net 当在ForEach循环中获取属性时?
我有一个带锁的属性getter,如下所示:.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循环时,何时获取属性?我的意思是,
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
的调用只发生一次,就在循环的开始处。这是一个很好的解释。谢谢。你最后忘记了处理枚举数的块。我们不要再为这个可怜的家伙操心了!如果他们真的想离开,确切地了解循环是如何扩展的,有比我的灰质更好的资源。