Beispiel #1
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="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 Get(TKey key, Func <TKey, T> replenisher, TimeSpan duration,
                     CacheGetMethod method = CacheGetMethod.Default, params string[] keys)
        {
            var gotValue = default(bool);

            return(TryGet(key, replenisher, duration, default(T), out gotValue, method, keys));
        }
Beispiel #2
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);
             }
         }
     }
 }
Beispiel #3
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);
                    }
                }
            }
        }