在列表(结构)中,我经常需要使用此代码修改项目的属性
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线程中执行,必须为
那么有更好的方法来修改列表结构中的项目吗?
感谢
答案 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