0
让 info = new SortedDictionary<string, string>

...

线程 A
--------
info.Add("abc", "def")

线程 B
--------
信息
|> Seq.iteri (fun i value -> ...

当我使用 iteri 函数时,我应该把 readLock 放在哪里?

4

2 回答 2

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"
于 2009-07-19T17:28:48.840 回答
0

经过一番思考,似乎在 Seq.iteri 上加锁实际上没有任何意义,因为 Seq 在 F# 中是惰性的。

然而,有趣的是,在序列的迭代过程中,当另一个线程插入字典的附加元素时会引发异常。不确定这对于惰性迭代是否完全有保证。

我现在的解决方案(作为一个函数)是:

(有趣_->
   锁定信息(有趣_->
                信息
                |> Seq.iteri (fun ix -> ...)))

我希望可以回答我自己的问题(我是新来的)。

于 2009-07-20T17:45:11.983 回答