let info = new SortedDictionary<string, string> ... Thread A -------- info.Add("abc", "def") Thread B -------- info |> Seq.iteri (fun i value -> ...
当我使用iteri函数时,我在哪里放置readLock?
答案 0 :(得分:1)
您可能只想解决可变性问题,并使用不可变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"
答案 1 :(得分:0)
经过一番思考后,似乎锁定Seq.iteri实际上没有任何意义,因为Seq在F#中是懒惰的。
然而,值得注意的是,在序列迭代期间,当另一个线程插入字典的其他元素时,会抛出异常。不确定是否完全保证了懒惰迭代。
我现在的解决方案(作为一项功能)是:
(fun _ -> lock info (fun _ -> info |> Seq.iteri (fun i x -> ...)))
我希望可以回答我自己的问题(我是新来的)。