如何执行在C#中的线程安全功能的memoization? [英] How to perform thread-safe function memoization in c#?

查看:138
本文介绍了如何执行在C#中的线程安全功能的memoization?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的堆栈溢出我已经发现的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?

推荐答案

您可以使用<一个href="http://msdn.microsoft.com/en-us/library/ee378676%28v=vs.110%29.aspx"><$c$c>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.

这篇关于如何执行在C#中的线程安全功能的memoization?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆