Here on stack overflow I've found the code that memoizes single-argument functions:
static Func<A, R> Memoize<A, R>(this Func<A, R> f)
{
var d = new Dictionary<A, R>();
return a=>
{
R r;
if (!d.TryGetValue(a, out r))
{
r = f(a);
d.Add(a, r);
}
return r;
};
}
While this code does its job for me, it fails sometimes when the memoized function is called from the multiple threads simultaneously: the Add method gets called twice with the same argument and throws an exception.
How can I make the memoization thread-safe?
You can use
ConcurrentDictionary.GetOrAddwhich does everything you need:The function
fshould be thread-safe itself, because it can be called from multiple threads simultaneously.This code also doesn't guarantee that function
fis called only once per unique argument value. It can be called many times, in fact, in the busy environment. If you need this kind of contract, you should take a look at the answers in this related question, but be warned that they're not as compact and require using locks.