2009-07-19 7 views

Répondre

1

Vous voudrez peut-être simplement contourner le problème de mutabilité et utiliser une carte immuable au lieu de SortedDictionary. De cette façon, votre itération fonctionne sur un «instantané» de la structure de données, sans que vous ayez à vous soucier de la changer. Ensuite, il vous suffit de verrouiller votre saisie initiale de l'instantané.

Par exemple (avertissement, n'ont pas testé pour voir si cela est en fait threadsafe!):

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

Le verrou ne serait-il pas libéré dans safefetch juste avant le démarrage de Map.iter? – Moonlight

+0

L'un des problèmes avec une carte est de savoir comment la passer d'un thread à un Dispatcher dans un autre thread? Chaque modification donnera une carte différente. Sauf si je mets en place une boîte aux lettres, je ne vois pas comment la transmettre. Une fermeture peut-être? – Moonlight

0

Après quelques réflexions, il semble que placer un verrou sur Seq.iteri ne fait en réalité aucun sens depuis un Seq est paresseux dans F #.

Cependant, il est intéressant de noter qu'une exception est levée lorsque des éléments supplémentaires d'un dictionnaire sont insérés par un autre thread pendant l'itération de la séquence. Je ne sais pas si c'est entièrement justifié pour une itération paresseuse.

Ma solution (en fonction) est en ce moment:

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

J'espère qu'il est correct de répondre à ma propre question (je suis nouveau ici).