Stream protection for high-performance in-memory cache

I have a static cache in memory, which is written only once per hour (or longer), and reading through many streams at an extremely high speed . Ordinary wisdom suggests that I follow a pattern, for example:

public static class MyCache
{
    private static IDictionary<int, string> _cache;
    private static ReaderWriterLockSlim _sharedLock;

    static MyCache()
    {
        _cache = new Dictionary<int, string>();
        _sharedLock = new ReaderWriterLockSlim();
    }

    public static string GetData(int key)
    {
        _sharedLock.EnterReadLock();
        try
        {
            string returnValue;
            _cache.TryGetValue(key, out returnValue);
            return returnValue;
        }
        finally
        {
            _sharedLock.ExitReadLock();
        }
    }

    public static void AddData(int key, string data)
    {
        _sharedLock.EnterWriteLock();
        try
        {
            if (!_cache.ContainsKey(key))
                _cache.Add(key, data);
        }
        finally
        {
            _sharedLock.ExitWriteLock();
        }
    }
}

-, read ? , . . (. ) ? , ? , , .

. , , # 4.x. *

public static class MyCache2
{
    private static IDictionary<int, string> _cache;
    private static object _fullLock;

    static MyCache2()
    {
        _cache = new Dictionary<int, string>();
        _fullLock = new object();
    }

    public static string GetData(int key)
    {
        //Note: There is no locking here... Is that ok?
        string returnValue;
        _cache.TryGetValue(key, out returnValue);
        return returnValue;
    }

    public static void AddData(int key, string data)
    {
        lock (_fullLock)
        {
            if (!_cache.ContainsKey(key))
                _cache.Add(key, data);
        }
    }
}
+5
5

, . , (, , ), , , :

public static class MyCache2
{
    private static IDictionary<int, string> _cache;

    static MyCache2()
    {
        _cache = new Dictionary<int, string>();
    }

    public static string GetData(int key)
    {
        string returnValue;
        _cache.TryGetValue(key, out returnValue);
        return returnValue;
    }

    public static void AddData(int key, string data)
    {
        IDictionary<int, string> clone = Clone(_cache);
        if (!clone.ContainsKey(key))
            clone.Add(key, data);
        Interlocked.Exchange(ref _cache, clone);
    }
}
+12

, . : , //etc . , . , , ( / ).

: , , , I.e.

var snapshot = someField;
// multiple reads on snapshot

, , , .

( ), . ( Interlocked.CompareExchange , ), , .

+6

:.net 1.x Hashtable ( , ) ; - , .

: Hashtable, , .

, - Hashtable, .net 4.x.

: , int , .

+2

. , , . , , .

, , , , catch, , , , .

public static class MyCache2
{
    private static IDictionary<int, string> _cache;
    private static IDictionary<int, string> _cacheClone;
    private static Object _lock;

    static MyCache2()
    {
        _cache = new Dictionary<int, string>();
        _lock = new Object();
    }

    public static string GetData(int key)
    {
        string returnValue;
        if (_cacheClone == null)
        {
            _cache.TryGetValue(key, out returnValue);
        }
        else
        {
            try
            {
                _cacheClone.TryGetValue(key, out returnValue);
            }
            catch
            {
                lock (_lock)
                {
                    _cache.TryGetValue(key, out returnValue);
                }
            }
        }
        return returnValue;
    }

    public static void AddData(int key, string data)
    {
        lock (_lock)
        {
            _cacheClone = Clone(_cache);
            if (!_cache.ContainsKey(key))
                _cache.Add(key, data);
            _cacheClone = null;
        }
    }
}
+1

All Articles