8 people like it.

Correct and Incorrect Way to Use ConcurrentDictionary

Correct and Incorrect Way to Use ConcurrentDictionary

Incorrect way

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
/// INCORRECT WAY:
let cachedCreateBad key =
    match myCache.TryGetValue key with
    | true, item -> item
    | _ -> 
        let newItem = createType()
        myCache.[key] <- newItem
        newItem

// Using like normal Dictionary is not correct.
// Because while calling createType() the 
// myCache is not locked so the addition can be out of sync.
// Also because of this, createType() call may execute in parallel 
// from multiple threads simultaneously for no reason.

Correct way

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
/// CORRECT WAY:
let cachedCreateGood key =
    myCache.GetOrAdd(key, fun key ->
        let newItem = createType()
        newItem)

// While the lambda is called there
// is a lightweight lock inside ConcurrentDictionary

// Notice that the code change between these is quite easy!
val cachedCreateBad : key:string -> string

Full name: Script.cachedCreateBad


 INCORRECT WAY:
val key : string
val myCache : System.Collections.Concurrent.ConcurrentDictionary<string,string>

Full name: Script.myCache
System.Collections.Concurrent.ConcurrentDictionary.TryGetValue(key: string, value: byref<string>) : bool
val item : string
val newItem : string
val createType : unit -> string

Full name: Script.createType
val cachedCreateGood : key:string -> string

Full name: Script.cachedCreateGood


 CORRECT WAY:
System.Collections.Concurrent.ConcurrentDictionary.GetOrAdd(key: string, value: string) : string
System.Collections.Concurrent.ConcurrentDictionary.GetOrAdd(key: string, valueFactory: System.Func<string,string>) : string

More information

Link:http://fssnip.net/7Qr
Posted:8 years ago
Author:Tuomas Hietanen
Tags: concurrency , concurrent , directory