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

时间:2009-12-30 13:49:13

标签: .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循环时,属性是否被获取?我的意思是,在这个循环中列表被锁定?在第一次检查?在每次迭代?整个循环?

For Each client as TcpClient in Me.ActiveClientList

Next

提前致谢!

4 个答案:

答案 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的调用只发生一次,就在循环开始时。