изменить свойство элемента в списке (структуры) - PullRequest
0 голосов
/ 07 января 2012

В списке (структуры) мне постоянно приходится модифицировать свойства предметов, используя этот код

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

Но это создает проблему, когда два или более элементов вызывают эту подпроцедуру. в этом один элемент, возможно, уже был удален. Этот код выполняется в потоке пользовательского интерфейса и должен быть

так есть ли лучший способ изменить элементы в структуре списка?

спасибо

Ответы [ 2 ]

1 голос
/ 08 января 2012

В вашем текущем коде вы не проверяете правильный элемент для существования (вы проверяете 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 голос
/ 07 января 2012

Вы должны заблокировать ресурсы, которые не являются потокобезопасными.Это гарантирует, что только один поток обращается к ним в данный момент времени.

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 
...