/// <summary> /// Removes an sql dependecy set on a HttpRuntime.Cache key. This method only removes /// the dependency, it does not purge the actual item from cache. /// </summary> /// <param name="key">The cache key.</param> public static void RemoveDependecy(string key) { SqlConnection con = new SqlConnection(_ConnectionString); DataAccessManager dam = new DataAccessManager(ConnectionString); dam.AddInputParameter("@CacheKey", key); dam.AddInputParameter("@ApplicationId", ClusteredCacheController.ApplicationId); try { dam.ExecuteNonQuery(GetFormattedStoredProcedureName(SP_DELETE)); } catch { throw; } finally { switch (ClusteredCacheController.ClusteredCachingMode) { case ClusteredCachingMode.ServiceBroker: #region service broker string dependencyId = GetDependencyIDFromCacheKey(key); if (!string.IsNullOrEmpty(dependencyId)) { _ServiceBrokerDependencies[dependencyId].SqlDependency.OnChange -= OnChange; _ServiceBrokerDependencies.Remove(dependencyId); } #endregion break; case ClusteredCachingMode.CheckAtRequest: CheckAtRequestDependencies.Remove(key); break; } } }
/// <summary> /// Removes an sql dependecy set on a HttpRuntime.Cache key. This method only removes /// the dependency, it does not purge the actual item from cache. /// </summary> public static void RemoveAllDependecies() { SqlConnection con = new SqlConnection(_ConnectionString); DataAccessManager dam = new DataAccessManager(ConnectionString); dam.AddInputParameter("@ApplicationId", ClusteredCacheController.ApplicationId); try { dam.ExecuteNonQuery(GetFormattedStoredProcedureName(SP_DELETE_ALL)); } catch { throw; } finally { switch (ClusteredCacheController.ClusteredCachingMode) { case ClusteredCachingMode.ServiceBroker: #region service broker _ServiceBrokerDependencies.Clear(); #endregion break; case ClusteredCachingMode.CheckAtRequest: CheckAtRequestDependencies.Clear(); break; } } }
/// <summary> /// Determines whether [is up to date] [the specified key]. /// </summary> /// <param name="key">The key.</param> /// <param name="synchTicks">The synch ticks.</param> /// <returns></returns> public static ClusteredCachingSynchronizationStatus IsUpToDate(string key, out long synchTicks) { #region check whether we can delay the synchronization check if (ClusteredCacheController.CheckAtRequestIsUpToDateDelayInMilliseconds > 0 && CheckAtRequestDependencies.ContainsKey(key) && CheckAtRequestDependencies[key].LastChecked.HasValue && CheckAtRequestDependencies[key].LastChecked.Value.AddMilliseconds(ClusteredCacheController.CheckAtRequestIsUpToDateDelayInMilliseconds) > DateTime.UtcNow) { synchTicks = CheckAtRequestDependencies[key].Ticks; return(ClusteredCachingSynchronizationStatus.UpToDate); } #endregion DataAccessManager dam = new DataAccessManager(ConnectionString); dam.AddInputParameter("@CacheKey", key); dam.AddInputParameter("@ApplicationId", ClusteredCacheController.ApplicationId); synchTicks = dam.ExecuteScalar <long>(GetFormattedStoredProcedureName(SP_SELECT)); if (synchTicks <= 0) { return(ClusteredCachingSynchronizationStatus.RemovedFromCollection); } else { if (CheckAtRequestDependencies.ContainsKey(key)) { if (CheckAtRequestDependencies[key].Ticks.Equals(synchTicks)) { if (ClusteredCacheController.CheckAtRequestIsUpToDateDelayInMilliseconds > 0) { CheckAtRequestDependencies[key] = GetCheckAtRequestInfo(synchTicks); } return(ClusteredCachingSynchronizationStatus.UpToDate); } else { return(ClusteredCachingSynchronizationStatus.OutOfDate); } } else { return(ClusteredCachingSynchronizationStatus.NotFound); } } }
/// <summary> /// Adds an object to the HttpRuntime.Cache collection and sets an SQL Dependency on it's /// key. /// </summary> /// <param name="key">The cache key.</param> /// <param name="item">The item to add to the cache.</param> /// <param name="priority">The priority.</param> public static void AddCacheItem(string key, object item, CacheItemPriority priority) { if (ClusteredCacheController.ClusteredCachingMode == ClusteredCachingMode.ServiceBroker) { if (_ServiceBrokerDependencies.ContainsKey(key)) { _ServiceBrokerDependencies.Remove(key); } } #region insert/update at database long utcNow = DateTime.UtcNow.Ticks; DataAccessManager dam = new DataAccessManager(ConnectionString); dam.AddInputParameter("@CacheKey", key); dam.AddInputParameter("@LastUpdate", utcNow); dam.AddInputParameter("@ApplicationId", ClusteredCacheController.ApplicationId); dam.ExecuteNonQuery(GetFormattedStoredProcedureName(SP_INSERT_UPDATE)); #endregion #region add to cache collection HttpRuntime.Cache.Remove(key); HttpRuntime.Cache.Insert(key, item, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, priority, null); #endregion #region add dependency switch (ClusteredCacheController.ClusteredCachingMode) { case ClusteredCachingMode.ServiceBroker: #region service broker SqlConnection con = new SqlConnection(_ConnectionString); SqlCommand cmd = new SqlCommand(GetFormattedStoredProcedureName(SP_SELECT), con); cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add("@CacheKey", SqlDbType.NVarChar, 256); cmd.Parameters[0].Value = key; // Clear any existing notifications cmd.Notification = null; // Create the dependency for this command SqlDependency dependency = new SqlDependency(cmd); // Add the event handler dependency.OnChange += new OnChangeEventHandler(OnChange); #region execute reader try { con.Open(); // Execute the command. cmd.ExecuteReader(); // Process the DataReader } catch (SqlException err) { DataAccessManager.ThrowDataAccessManagerException(err, GetFormattedStoredProcedureName(SP_SELECT)); } finally { con.Close(); } #endregion _ServiceBrokerDependencies.Add(dependency.Id, new CacheKeySqlDependency() { CacheKey = key, SqlDependency = dependency }); #endregion break; case ClusteredCachingMode.CheckAtRequest: if (CheckAtRequestDependencies.ContainsKey(key)) { CheckAtRequestDependencies[key] = GetCheckAtRequestInfo(utcNow); } else { CheckAtRequestDependencies.Add(key, GetCheckAtRequestInfo(utcNow)); } break; } #endregion }
/// <summary> /// Gets an item with a specified key from the HttpRuntime.Cache. /// </summary> /// <param name="key">The cache key.</param> /// <param name="loadObj">The delegate returning the item to insert into cache when it doesn't exist.</param> /// <param name="priority">The priority.</param> /// <param name="autoInsertDependency">If set to true, a dependency will be automatically created when no cache /// dependency is currently set. If this value is false and you try to retrieve an item from cache that was not added /// first, this method will return null.</param> /// <returns> /// The cached item when present at HttpRuntime.Cache, the loadObj delegate (which re-adds the item /// at cache) when the item can't be found at cache, null if the cache item dependency doesn't exist and autoInsertDependency /// is set to false or the loadObj delegate returned null. /// </returns> public static object GetCacheItem(string key, ReloadObjectAtCache loadObj, CacheItemPriority priority, bool autoInsertDependency) { object fetchedItem = null; switch (ClusteredCacheController.ClusteredCachingMode) { case ClusteredCachingMode.ServiceBroker: #region service broker lock (_CacheLock) { if (HttpRuntime.Cache[key] == null) { // check whether we have a dependency... string dependencyId = GetDependencyIDFromCacheKey(key); if (!string.IsNullOrEmpty(dependencyId) || autoInsertDependency) { // we actually have a dependency, so refresh the cache... try { fetchedItem = loadObj(); } catch (Exception err) { throw new CachingException("Error at loading object into cache. See the inner exception for further details.", err); } if (fetchedItem == null) { // we can't insert null as an object, so simply return null. return(null); } HttpRuntime.Cache.Insert(key, fetchedItem, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, priority, null); return(fetchedItem); } else { // this key doesn't exist and there is no associated dependency, so return null... return(null); } } return(HttpRuntime.Cache[key]); } #endregion case ClusteredCachingMode.CheckAtRequest: #region Check at request long synchTicks = -1; lock (_CacheLock) { ClusteredCachingSynchronizationStatus status = IsUpToDate(key, out synchTicks); switch (status) { case ClusteredCachingSynchronizationStatus.UpToDate: if (HttpRuntime.Cache[key] == null) { try { fetchedItem = loadObj(); } catch (Exception err) { throw new CachingException("Error at loading object into cache. See the inner exception for further details.", err); } if (fetchedItem == null) { // we can't insert null as an object, so simply return null. return(null); } HttpRuntime.Cache.Insert(key, fetchedItem, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, priority, null); return(fetchedItem); } return(HttpRuntime.Cache[key]); case ClusteredCachingSynchronizationStatus.OutOfDate: CheckAtRequestDependencies[key] = GetCheckAtRequestInfo(synchTicks); HttpRuntime.Cache.Remove(key); try { fetchedItem = loadObj(); } catch (Exception err) { throw new CachingException("Error at loading object into cache. See the inner exception for further details.", err); } if (fetchedItem == null) { // we can't insert null as an object, so simply return null. return(null); } HttpRuntime.Cache.Insert(key, fetchedItem, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, priority, null); return(fetchedItem); case ClusteredCachingSynchronizationStatus.NotFound: CheckAtRequestDependencies.Add(key, GetCheckAtRequestInfo(synchTicks)); HttpRuntime.Cache.Remove(key); try { fetchedItem = loadObj(); } catch (Exception err) { throw new CachingException("Error at loading object into cache. See the inner exception for further details.", err); } if (fetchedItem == null) { // we can't insert null as an object, so simply return null. return(null); } HttpRuntime.Cache.Insert(key, fetchedItem, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, priority, null); return(fetchedItem); case ClusteredCachingSynchronizationStatus.RemovedFromCollection: if (autoInsertDependency) { try { fetchedItem = loadObj(); } catch (Exception err) { throw new CachingException("Error at loading object into cache. See the inner exception for further details.", err); } AddCacheItem(key, fetchedItem, priority); return(fetchedItem); } else { HttpRuntime.Cache.Remove(key); CheckAtRequestDependencies.Remove(key); return(null); } } break; } #endregion } return(null); }