Exemple #1
0
        /// <summary>
        /// Clears the cache of the specified keys.
        /// </summary>
        /// <param name="keys">The keys to clear the cache of.</param>
        /// <param name="cleared">
        /// Were the keys cleared successfully?
        /// </param>
        public void ClearKeys(IEnumerable <TKey> keys, out bool cleared)
        {
            var lockTaken = default(bool);

            try
            {
                Monitor.TryEnter(InstancesLock, LockTimeout, ref lockTaken);
                if (lockTaken)
                {
                    foreach (var key in keys)
                    {
                        Instances.Remove(key);
                    }
                    cleared = true;
                }
                else
                {
                    CacheSettings.FailedLockHandler(LockTimeout);
                    cleared = false;
                }
            }
            finally
            {
                if (lockTaken)
                {
                    Monitor.Exit(InstancesLock);
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Clears the cache.
        /// </summary>
        /// <param name="cleared">
        /// Was the cache cleared successfully?
        /// </param>
        public void Clear(out bool cleared)
        {
            var lockTaken = default(bool);

            try
            {
                Monitor.TryEnter(InstancesLock, LockTimeout, ref lockTaken);
                if (lockTaken)
                {
                    Instances.Clear();
                    cleared = true;
                }
                else
                {
                    CacheSettings.FailedLockHandler(LockTimeout);
                    cleared = false;
                }
            }
            finally
            {
                if (lockTaken)
                {
                    Monitor.Exit(InstancesLock);
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// Indicates whether or not an instance was cached by the specified keys.
        /// </summary>
        /// <param name="successful">
        /// Was the check successful (e.g., wouldn't be successful if the lock
        /// timeout expired).
        /// </param>
        /// <param name="keys">
        /// Optional. The keys to store/retrieve a value by. Each key combination will
        /// be treated as a separate cache.
        /// </param>
        /// <returns>
        /// True, if an item was cached by the specified keys; otherwise, false.
        /// </returns>
        public bool WasCached(out bool successful, params string[] keys)
        {
            var lockTaken = default(bool);

            try
            {
                Monitor.TryEnter(InstanceLock, LockTimeout, ref lockTaken);
                if (lockTaken)
                {
                    successful = true;
                    return(LastCache.HasValue
                        ? Instances.ContainsKey(keys)
                        : false);
                }
                else
                {
                    CacheSettings.FailedLockHandler(LockTimeout);
                    successful = false;
                    return(false);
                }
            }
            finally
            {
                if (lockTaken)
                {
                    Monitor.Exit(InstanceLock);
                }
            }
        }
Exemple #4
0
        /// <summary>
        /// Trys to get the value by the specified keys.
        /// </summary>
        /// <param name="keys">
        /// The keys.
        /// </param>
        /// <param name="gotValue">
        /// True, if an existing value was retrieved; otherwise, false.
        /// </param>
        /// <returns>
        /// The value, or the default for the type.
        /// </returns>
        private T TryGetByKeys(string[] keys, out bool gotValue)
        {
            var chosenKeys = keys ?? EmptyArray;
            var value      = default(T);
            var lockTaken  = default(bool);

            try
            {
                Monitor.TryEnter(InstanceLock, LockTimeout, ref lockTaken);
                if (lockTaken)
                {
                    if (Instances.TryGetValue(chosenKeys, out value))
                    {
                        gotValue = true;
                        return(value);
                    }
                    else
                    {
                        gotValue = false;
                        return(default(T));
                    }
                }
                else
                {
                    CacheSettings.FailedLockHandler(LockTimeout);
                    gotValue = false;
                    return(default(T));
                }
            }
            finally
            {
                if (lockTaken)
                {
                    Monitor.Exit(InstanceLock);
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// Trys to get the value by the specified keys.
        /// </summary>
        /// <param name="keys">
        /// The keys.
        /// </param>
        /// <param name="accessKey">
        /// The key to use to access the value.
        /// </param>
        /// <param name="gotValue">
        /// True, if an existing value was retrieved; otherwise, false.
        /// </param>
        /// <returns>
        /// The value, or the default for the type.
        /// </returns>
        private T TryGetByKeys(string[] keys, TKey accessKey, out bool gotValue)
        {
            var chosenKeys = keys ?? EmptyArray;
            var value      = default(T);
            var lockTaken  = default(bool);

            try
            {
                Monitor.TryEnter(InstancesLock, LockTimeout, ref lockTaken);
                if (lockTaken)
                {
                    var valueDictionary = default(Tuple <Dictionary <string[], T>, DateTime>);
                    if (Instances.TryGetValue(accessKey, out valueDictionary))
                    {
                        if (valueDictionary.Item1.TryGetValue(chosenKeys, out value))
                        {
                            gotValue = true;
                            return(value);
                        }
                    }
                }
                else
                {
                    CacheSettings.FailedLockHandler(LockTimeout);
                }
            }
            finally
            {
                if (lockTaken)
                {
                    Monitor.Exit(InstancesLock);
                }
            }
            gotValue = false;
            return(default(T));
        }
Exemple #6
0
 /// <summary>
 /// Gets the instance variable (either from the cache or from the specified function).
 /// </summary>
 /// <param name="key">
 /// The key to use when fetching the variable.
 /// </param>
 /// <param name="replenisher">
 /// The function that replenishes the cache.
 /// </param>
 /// <param name="duration">
 /// The duration to cache for.
 /// </param>
 /// <param name="defaultValue">
 /// The value to use in the event that a value could not be retrieved (e.g.,
 /// if the lock could not be achieved within the timeout).
 /// </param>
 /// <param name="gotValue">
 /// Was the value retrieved, or was the default value used instead?
 /// </param>
 /// <param name="method">
 /// Optional. The cache method to use when retrieving the value.
 /// </param>
 /// <param name="keys">
 /// Optional. The keys to store/retrieve a value by. Each key combination will
 /// be treated as a separate cache.
 /// </param>
 /// <returns>
 /// The value.
 /// </returns>
 public T TryGet(TKey key, Func <TKey, T> replenisher, TimeSpan duration, T defaultValue,
                 out bool gotValue, CacheGetMethod method = CacheGetMethod.Default, params string[] keys)
 {
     // Which cache retrieval method should be used?
     if (method == CacheGetMethod.FromCache)
     {
         // Get directly from cache.
         var lockTaken = default(bool);
         try
         {
             Monitor.TryEnter(InstancesLock, LockTimeout, ref lockTaken);
             if (lockTaken)
             {
                 return(TryGetByKeys(keys, key, out gotValue));
             }
             else
             {
                 CacheSettings.FailedLockHandler(LockTimeout);
                 gotValue = false;
                 return(defaultValue);
             }
         }
         finally
         {
             if (lockTaken)
             {
                 Monitor.Exit(InstancesLock);
             }
         }
     }
     else if (method == CacheGetMethod.NoCache)
     {
         // Get directly from replenisher.
         var returnValue = replenisher(key);
         gotValue = true;
         return(returnValue);
     }
     else
     {
         var lockTaken = default(bool);
         try
         {
             Monitor.TryEnter(InstancesLock, LockTimeout, ref lockTaken);
             if (lockTaken)
             {
                 var tempInstance = default(T);
                 var now          = DateTime.Now;
                 if (method == CacheGetMethod.Recache)
                 {
                     // Force the cache to replenish.
                     tempInstance = replenisher(key);
                     gotValue     = true;
                     UpdateValueByKeysWithoutLock(keys, key, tempInstance, now);
                 }
                 else
                 {
                     // Value already cached?
                     var tempTuple = default(Tuple <Dictionary <string[], T>, DateTime>);
                     if (Instances.TryGetValue(key, out tempTuple) && tempTuple.Item1.ContainsKey(keys))
                     {
                         if (now.Subtract(Instances[key].Item2) >= duration)
                         {
                             if (method == CacheGetMethod.NoStore)
                             {
                                 // Cache expired. Get a new value without modifying the cache.
                                 tempInstance = replenisher(key);
                                 gotValue     = true;
                             }
                             else
                             {
                                 // Cache expired. Replenish the cache.
                                 tempInstance = replenisher(key);
                                 gotValue     = true;
                                 UpdateValueByKeysWithoutLock(keys, key, tempInstance, now);
                             }
                         }
                         else
                         {
                             // Cache still valid. Use cached value.
                             tempInstance = TryGetByKeys(keys, key, out gotValue);
                         }
                     }
                     else
                     {
                         if (method == CacheGetMethod.NoStore)
                         {
                             // No cached value. Get a new value without modifying the cache.
                             tempInstance = replenisher(key);
                             gotValue     = true;
                         }
                         else
                         {
                             // No cached value. Replenish the cache.
                             tempInstance = replenisher(key);
                             gotValue     = true;
                             UpdateValueByKeysWithoutLock(keys, key, tempInstance, now);
                         }
                     }
                 }
                 return(tempInstance);
             }
             else
             {
                 CacheSettings.FailedLockHandler(LockTimeout);
                 gotValue = false;
                 return(defaultValue);
             }
         }
         finally
         {
             if (lockTaken)
             {
                 Monitor.Exit(InstancesLock);
             }
         }
     }
 }
Exemple #7
0
        /// <summary>
        /// Gets the instance variable (either from the cache or from the specified function).
        /// </summary>
        /// <param name="duration">
        /// The duration to cache for.
        /// </param>
        /// <param name="replenisher">
        /// The function that replenishes the cache.
        /// </param>
        /// <param name="defaultValue">
        /// The value to use in the event that a value could not be retrieved (e.g.,
        /// if the lock could not be achieved within the timeout).
        /// </param>
        /// <param name="gotValue">
        /// Was the value retrieved, or was the default value used instead?
        /// </param>
        /// <param name="method">
        /// Optional. The cache method to use when retrieving the value.
        /// </param>
        /// <param name="keys">
        /// Optional. The keys to store/retrieve a value by. Each key combination will
        /// be treated as a separate cache.
        /// </param>
        /// <returns>
        /// The value.
        /// </returns>
        public T TryGet(TimeSpan duration, Func <T> replenisher, T defaultValue, out bool gotValue,
                        CacheGetMethod method = CacheGetMethod.Default, params string[] keys)
        {
            // Which cache retrieval method should be used?
            if (method == CacheGetMethod.FromCache)
            {
                // Get directly from cache.
                var lockTaken = default(bool);
                try
                {
                    Monitor.TryEnter(InstanceLock, LockTimeout, ref lockTaken);
                    if (lockTaken)
                    {
                        if (LastCache.HasValue)
                        {
                            var returnValue = TryGetByKeys(keys, out gotValue);
                            return(returnValue);
                        }
                        else
                        {
                            gotValue = false;
                            return(defaultValue);
                        }
                    }
                    else
                    {
                        CacheSettings.FailedLockHandler(LockTimeout);
                        gotValue = false;
                        return(defaultValue);
                    }
                }
                finally
                {
                    if (lockTaken)
                    {
                        Monitor.Exit(InstanceLock);
                    }
                }
            }
            else if (method == CacheGetMethod.NoCache)
            {
                // Get directly from replenisher.
                var returnValue = replenisher();
                gotValue = true;
                return(returnValue);
            }
            else
            {
                var returnValue = defaultValue;
                var lockTaken   = default(bool);
                try
                {
                    Monitor.TryEnter(InstanceLock, LockTimeout, ref lockTaken);
                    if (lockTaken)
                    {
                        // Variables.
                        var now = DateTime.Now;

                        // Force a cache update?
                        if (method == CacheGetMethod.Recache)
                        {
                            UpdateValueByKeys(keys, replenisher());
                        }

                        // Update cache if it's expired.
                        else if (!LastCache.HasValue || !Instances.ContainsKey(keys) ||
                                 now.Subtract(LastCache.Value) >= duration)
                        {
                            // Get new value?
                            if (method == CacheGetMethod.NoStore)
                            {
                                returnValue = replenisher();
                                gotValue    = true;
                                return(returnValue);
                            }

                            // Update cache with new value.
                            else
                            {
                                UpdateValueByKeys(keys, replenisher());
                                LastCache = now;
                            }
                        }

                        // Return value.
                        returnValue = TryGetByKeys(keys, out gotValue);
                        return(returnValue);
                    }
                    else
                    {
                        CacheSettings.FailedLockHandler(LockTimeout);
                        gotValue = false;
                        return(defaultValue);
                    }
                }
                finally
                {
                    if (lockTaken)
                    {
                        Monitor.Exit(InstanceLock);
                    }
                }
            }
        }