2012-01-07 229 views
0

在列表(结构),我一直在使用这个代码modifiy项财产

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 

到modifiy项目的属性(结构)列表,但是这个给问题,当两个或两个以上的项目调用这个子程序。其中一件物品可能已被删除。此代码在UI线程中执行,并且必须是

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

谢谢

+0

为什么WebWorker是结构而不是类? – 2012-01-07 18:02:18

+0

@ Meta-Knight在课堂上有什么不同,有什么优势? – Smith 2012-01-07 18:32:19

+0

如果WebWorker是一个类,则不需要删除并再次添加该项目。最好的做法是几乎总是使用一个类,除非你有一个不可变的数据结构。 – 2012-01-07 19:53:08

回答

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 
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 
+0

该应用程序不是多线程的,但是使用多个webbrowser来完成一些工作。这是否适用于这里 – Smith 2012-01-07 19:37:32

+0

如果该应用程序不是多线程的,那么如何删除一个项目两次? – 2012-01-07 20:17:02