我有一个像这样的锁的属性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
提前致谢!
答案 0 :(得分:2)
在上面的场景中,首次初始化for循环时会获得一次锁定。返回列表并释放锁定,然后开始迭代。
答案 1 :(得分:2)
Me.ActiveClientList将为您提供对m_activeClientList的引用,因此将一次获取此引用(在循环启动并使用锁定)并在整个循环中使用。所以这意味着如果列表中的元素在循环期间发生变化(通过其他线程),则不会受到保护。
但是,如果您要实现的是同步访问列表(例如,如果它是共享列表或其他内容),请检查此链接: How to synchronize the access to a List<T> used in ASP.NET?
您可以锁定SyncRoot
以锁定对列表的访问权限。
答案 2 :(得分:2)
你的锁码只会锁定return语句,而不会锁定其他内容 没有可能会锁定多个语句的情况。
For Each
循环将读取属性一次,然后调用GetEnumerator
。
答案 3 :(得分:2)
For Each
实际上是语法糖。编译器将其扩展为:
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#男孩)。
正如您所看到的,对ActiveClientList
的调用只发生一次,就在循环开始时。