下面的堆栈溢出我已经发现的code表示memoizes单参数功能:
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;
};
}
虽然这code做了这个工作对我来说,这有时会失败时memoized功能,同时从多个线程调用:在添加
方法被调用两次相同的参数,并抛出一个异常。
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?
推荐答案
您可以使用ConcurrentDictionary.GetOrAdd它做了你需要的一切:
You can use ConcurrentDictionary.GetOrAdd
which does everything you need:
static Func<A, R> ThreadsafeMemoize<A, R>(this Func<A, R> f)
{
var cache = new ConcurrentDictionary<A, R>();
return argument => cache.GetOrAdd(argument, f);
}
功能 F
应该是线程安全的本身,因为它可以从多个线程同时调用。
The function f
should be threadsafe itself, because it can be called from multiple threads simultaneously.
这code也不能保证功能可按 F
被称为每个唯一参数值只有一次。它可以被调用多次,事实上,在繁忙的环境。如果你需要这样的合同,你应该看一看在这个相关问题的答案,但被警告,他们是不紧凑,并且需要使用锁。
This code also doesn't guarantee that funciton f
is 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.
相关推荐
最新文章