1

假设我有一个 IEnumerable,例如 List(TValue),并且我想跟踪是否正在访问该列表(以防止出现问题,例如,在不同线程上迭代列表时添加到列表);我总是可以编写如下代码:

Dim List1 As New List(Of Integer)
Dim IteratingList1 As Boolean = False

' ... some code ... '

Private Function getSumOfPositivesFromList1() As Integer
    If IteratingList1 Then Return -1

    IteratingList1 = True

    Dim SumOfPositives As Integer = 0

    For Each x As Integer In List1
        If x > 0 Then SumOfPositives += x
    Next

    IteratingList1 = False

    Return SumOfPositives
End Function

(我意识到这段代码非常随意,但它说明了我在说什么。)

我的问题是是否有比手动更新和访问布尔值更好/更清洁的方法来执行此检查,如上所述。我觉得必须有,但据我所知,没有任何 IEnumerable 类具有内置的“我正在迭代”方法或属性。编写一个实现 IEnumerable 并包含这样一个属性的新类对我来说似乎有点矫枉过正。

4

3 回答 3

3

Afaik,在 VB.NET 中,您可以SyncLock在访问对象时使用 锁定对象,以防止其他线程同时对其进行处理。

Public Shared objStorageLock As New Object

Private Function getSumOfPositivesFromList1() As Integer

    Dim SumOfPositives As Integer = 0

    SyncLock objStorageLock 

    For Each x As Integer In List1
        If x > 0 Then SumOfPositives += x
    Next

    End SyncLock

    Return SumOfPositives
End Function
于 2009-05-19T13:32:15.600 回答
1

这取决于你在做什么,如果你担心对列表的多次写入访问Synclock是要走的路。

如果您在枚举期间消除了异常,那么有时最好获取一个副本并枚举,例如

For Each Num as Integer in SumOfPositives.ToArray()
...
Next Num

显然,您可能需要考虑您的 RAM 使用情况和性能等,但通常这工作得很好而且很快。

于 2009-05-19T13:37:42.810 回答
1

如果存在合适的函数,VB.net 将使用 GetEnumerator 函数,而不是使用 IEnumerable 接口。因此可以实现 IEnumerable 但调用为实现 IEnumerable.GetEnumerator 的方法提供了一些其他名称。由于大多数其他枚举某些东西的例程将使用 IEnumerable 而不是鸭式 GetEnumerator,因此 GetEnumerator 方法本身被调用的事实表明它被 for-each 循环所使用。

于 2011-02-01T15:45:59.290 回答