public static void EnsureIsStarted(Key key, ICacheItemRecalculationStrategy recalculationStrategy, MethodInterceptionArgs args, ICache cache) { var keyString = key.ToString(); Ensure.That<NHelpfulException.FrameworkExceptions.ArgumentException>(keyString.Length.IsLessThanOrEqualTo(260), "key must be less than 260 characters long."); try { bool createdNew; var mutex = new Mutex(false, MutexPrefix + keyString, out createdNew); if (createdNew) { if (cache[keyString].IsNotNull()) return; //item already in cache, assume thread already started TODO: possibly log this as an error ThreadPool.QueueUserWorkItem( o => recalculationStrategy.RunRoutine(key, args, cache, mutex, args.Proceed)); //NOTE: mutex.ReleaseMutex(); is not called because the mutex is only expected to be released upon closure of the application } } catch (Exception) { //log exception throw; } }
/// <remarks> /// Consider alternatives to instantiating instances /// of the specified types using Activator.CreateInstance. /// </remarks> public override void OnInvoke(MethodInterceptionArgs args) { Ensure.That<ArgumentNullException>(args.IsNotNull(), "args"); _cache = (ICache) Activator.CreateInstance(_cacheType); _keyCreationStrategy = (IFriendlyNameCreationStrategy) Activator.CreateInstance(_keyCreationStrategyType); if (_recalculationStrategyType.IsNotNull()) { _recalculationStrategy = (ICacheItemRecalculationStrategy) Activator.CreateInstance(_recalculationStrategyType, _durationToRecalculate); } var friendlyName = _keyCreationStrategy.GenerateFriendlyName(args); var key = _durationToStore == default(TimeSpan) //infer from the variables set, the key type to create? ? new Key(DefaultCacheDuration, DefaultCacheExpirationType, friendlyName) : new Key(_durationToStore, _storageStyle, _expirationType, friendlyName); object cacheItem; if ((cacheItem = _cache[key.ToString()]).IsNotNull()) { args.ReturnValue = cacheItem; } else { args.Proceed(); _cache.Add(key, args.ReturnValue); if (_recalculationStrategy.IsNotNull()) AsyncCacheItemRecalculator.EnsureIsStarted(key, _recalculationStrategy, args, _cache); } }