修改列表中的项属性(结构)

时间:2012-01-07 16:45:48

标签: .net vb.net winforms .net-2.0 generic-list

在列表(结构)中,我经常需要使用此代码修改项目的属性

Private Sub ChangeState(ByVal ww As WebWorker, _
                        ByVal NewState As WorkerState)
        Dim oWBB As WebWorker = ListWebWorkers.Find(Function(item As WebWorker) item.Browser.Name.ToLower = ww.Browser.Name.ToLower)
        If oWBB.Browser IsNot Nothing Then
            ListWebWorkers.Remove(oWBB)
            oWBB = ww
            oWBB.State = NewState
            ListWebWorkers.Add(oWBB)
        End If
    End Sub

但是当两个或多个项目调用此子过程时,这会产生问题。可能已经删除了一个项目。此代码在ui线程中执行,必须为

那么有更好的方法来修改列表结构中的项目吗?

感谢

2 个答案:

答案 0 :(得分:1)

您必须锁定非线程安全的资源。这可确保在给定时间只有一个线程正在访问它们。

Private Sub ChangeState(ByVal ww As WebWorker, _ 
                    ByVal NewState As WorkerState) 

    SyncLock ListWebWorkers
        Dim oWBB As WebWorker = ListWebWorkers.Find(Function(item As WebWorker) item.Browser.Name.ToLower = ww.Browser.Name.ToLower) 
        If oWBB.Browser IsNot Nothing Then 
            ListWebWorkers.Remove(oWBB) 
            oWBB = ww 
            oWBB.State = NewState 
            ListWebWorkers.Add(oWBB) 
        End If 
    End SyncLock 
End Sub 

答案 1 :(得分:1)

在您当前的代码中,您没有检查正确的项目是否存在(您正在检查oWBB.Browser,但您应该检查oWBB。此外,它不是线程安全的。

如果使用ConcurrentDictionary代替,则以线程安全的方式验证项目是否存在会更容易。

以下是重写代码的示例:

' Create a dictionary with case-insensitive keys
Private Shared ListWebWorkers As New System.Collections.Concurrent.ConcurrentDictionary(Of String, WebWorker)(StringComparer.InvariantCultureIgnoreCase)

Private Sub ChangeState(ByVal ww As WebWorker, ByVal NewState As WorkerState)

    If ListWebWorkers.ContainsKey(ww.Browser.Name) Then
        ListWebWorkers.TryRemove(ww.Browser.Name)
        ww.State = NewState
        ListWebWorkers.TryAdd(ww.Browser.Name, ww)
    End If
End Sub