Синхронизация SortedDictionary.iteri с использованием блокировки чтения и записи - PullRequest
0 голосов
/ 19 июля 2009
let info = new SortedDictionary<string, string>

...

Thread A
--------
info.Add("abc", "def")

Thread B
--------
info
|> Seq.iteri (fun i value ->  ...

Где разместить readLock при использовании функции iteri?

Ответы [ 2 ]

1 голос
/ 19 июля 2009

Вы можете просто обойти проблему изменчивости и использовать неизменяемый объект Map вместо SortedDictionary. Таким образом, ваша итерация работает с «снимком» структуры данных, не беспокоясь о том, что она изменится из-под вас. Затем вам нужно только заблокировать первоначальный захват снимка.

Например (предупреждение, не проверялось, действительно ли это потокобезопасно!):

let mymap = ref Map<string,string>.Empty

let safefetch m = lock(m) (fun () -> !m)
let safeadd k v m = lock(m) (fun () -> m := Map.add k v !m)

mymap
|> safefetch
|> Map.iter ( fun k v -> printfn "%s: %s" k v )

mymap |> safeadd "test" "value"
0 голосов
/ 20 июля 2009

После некоторых размышлений кажется, что наложение блокировки на Seq.iteri на самом деле не имеет смысла, поскольку Seq ленив в F #.

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

Мое решение (как функция) прямо сейчас:

(fun _ -> 
   lock info (fun _ ->
                info
                |> Seq.iteri (fun i x -> ...)))

Я надеюсь, что можно ответить на мой собственный вопрос (я новичок здесь).

...