试图在3.5项目中实现ConcurrentDictionary.GetOrAdd

时间:2015-04-01 10:47:25

标签: c# concurrency .net-3.5

在.Net 4.5项目中,我使用一种简单的实用工具方法以线程安全的方式记忆结果(实际上是一个Web应用程序):

public static class FuncUtilities
{
    public static Func<TArg, TResult> ThreadsafeMemoize<TArg, TResult>(Func<TArg, TResult> f)
    {
        var cache = new ConcurrentDictionary<TArg, TResult>();

        return arg => cache.GetOrAdd(arg, f);
    }

    public static Func<TArg, TArg2, TResult> ThreadsafeMemoize<TArg, TArg2, TResult>(Func<TArg, TArg2, TResult> f)
    {
        var cache = new ConcurrentDictionary<Tuple<TArg, TArg2>, TResult>();
        return (arg, arg2) =>
        {
            var key = new Tuple<TArg, TArg2>(arg, arg2);
            return cache.GetOrAdd(key, f(arg, arg2));
        };
    }

    public static Func<TArg, TArg2, TArg3, TResult> ThreadsafeMemoize<TArg, TArg2, TArg3, TResult>(Func<TArg, TArg2, TArg3, TResult> f)
    {
        var cache = new ConcurrentDictionary<Tuple<TArg, TArg2, TArg3>, TResult>();
        return (arg, arg2, arg3) =>
        {
            var key = new Tuple<TArg, TArg2, TArg3>(arg, arg2, arg3);
            return cache.GetOrAdd(key, f(arg, arg2, arg3));
        };
    }
}

在另一个项目中,必须以3.5运行,我有相同的记忆结果的要求。

如何将我的代码移植到.Net 3.5?

found partial port of the class,但它缺少GetOrAdd方法,所以我尝试自己实现它:

public class ConcurrentDictionary<TKey, TValue>
{
    private readonly object _Padlock = new object();

    private readonly Dictionary<TKey, TValue> _Dictionary = new Dictionary<TKey, TValue>();

    public TValue this[TKey key]
    {
        get { lock (_Padlock) { return _Dictionary[key]; } }
        set { lock (_Padlock) { _Dictionary[key] = value; } }
    }

    public bool TryGetValue(TKey key, out TValue value)
    {
        lock (_Padlock)
        {
            return _Dictionary.TryGetValue(key, out value);
        }
    }

    public TValue GetOrAdd(TKey key, Func<TKey, TValue> factory)
    {
        lock (_Padlock)
        {
            if (!_Dictionary.ContainsKey(key))
            {
                _Dictionary.Add(key, factory(key));
            }
            return _Dictionary[key];
        }
    }
}

我还必须&#34;模拟&#34;嵌套Tuple

KeyValuePair课程
public static class FuncUtilities
{
    public static Func<TArg, TResult> ThreadsafeMemoize<TArg, TResult>(Func<TArg, TResult> f)
    {
        var cache = new ConcurrentDictionary<TArg, TResult>();

        return arg => cache.GetOrAdd(arg, f);
    }

    public static Func<TArg, TArg2, TResult> ThreadsafeMemoize<TArg, TArg2, TResult>(Func<TArg, TArg2, TResult> f)
    {
        var cache = new ConcurrentDictionary<KeyValuePair<TArg, TArg2>, TResult>();
        return (arg, arg2) =>
        {
            var key = new KeyValuePair<TArg, TArg2>(arg, arg2);
            return cache.GetOrAdd(key, f(arg, arg2));
        };
    }

    public static Func<TArg, TArg2, TArg3, TResult> ThreadsafeMemoize<TArg, TArg2, TArg3, TResult>(Func<TArg, TArg2, TArg3, TResult> f)
    {
        var cache = new ConcurrentDictionary<KeyValuePair<KeyValuePair<TArg, TArg2>, TArg3>, TResult>();
        return (arg, arg2, arg3) =>
        {
            var key = new KeyValuePair<KeyValuePair<TArg, TArg2>, TArg3>(new KeyValuePair<TArg, TArg2>(arg, arg2), arg3);
            return cache.GetOrAdd(key, f(arg, arg2, arg3));
        };
    }
}

不幸的是,这不会编译:

  

1&GT; C:\一些\ FuncUtilities.cs(29,24,29,57):   错误CS1502:最佳重载方法匹配   &#39; some.ConcurrentDictionary,TResult&GT; .GetOrAdd(System.Collections.Generic.KeyValuePair,   System.Func,TResult&GT;)&#39;   有一些无效的论点   1 GT; C:\一些\ FuncUtilities.cs(29,44,29,56):   错误CS1503:参数2:无法转换为&#39; TResult&#39;至   &#39; System.Func,TResult&GT;&#39;   1 GT; C:\一些\ FuncUtilities.cs(39,24,39,63):   错误CS1502:最佳重载方法匹配   &#39; some.ConcurrentDictionary,TArg3&GT;,&TResult GT; .GetOrAdd(System.Collections.Generic.KeyValuePair,TArg3&gt;中   System.Func,TArg3&GT;,&TResult GT;)&#39;   有一些无效的论点   1 GT; C:\一些\ FuncUtilities.cs(39,44,39,62):   错误CS1503:参数2:无法转换为&#39; TResult&#39;至   &#39; System.Func,TArg3&GT;,&TResult GT;&#39;

0 个答案:

没有答案