let myCache = new System.Collections.Concurrent.ConcurrentDictionary() let createType() = "some method" // [snippet:Incorrect way] /// 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. // [/snippet] // [snippet:Correct way] /// 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! // [/snippet]