public override void Set(string key, object entry, DateTime utcExpiry)
        {
            Debug.WriteLine("Cache.Set(" + key + ", " + entry + ", " + utcExpiry + ")");

            var item = new CacheItem { Expires = utcExpiry, Item = entry };
            _items[key] = item;
        }
Ejemplo n.º 2
0
 private static void AddCacheObject(CacheItem cache)
 {
     if (cache.Cache[cache.Name] == null)
     {
         cache.Cache.Add(cache.Name, cache, null,
              DateTime.Now.AddMinutes(_numberOfMinutes), Cache.NoSlidingExpiration,
              CacheItemPriority.NotRemovable, CacheCallback);
     }
 }
Ejemplo n.º 3
0
        public static void Run(string name, int minutes, Callback callbackMethod)
        {
            _numberOfMinutes = minutes;

            CacheItem cache = new CacheItem();
            cache.Name = name;
            cache.Callback = callbackMethod;
            cache.Cache = HttpRuntime.Cache;
            cache.LastRun = DateTime.Now;
            AddCacheObject(cache);
        }
Ejemplo n.º 4
0
		public bool TryGetValue (string key, out CacheItem value)
		{
			LinkedListNode <CacheItem> item;
			
			if (dict.TryGetValue (key, out item)) {
				value = item.Value;
				return true;
			}
			value = null;
			return false;
		}
Ejemplo n.º 5
0
        public CacheScheduler Run(string cacheItemName, Callback callbackMethod)
        {
            CacheItem cache = new CacheItem();

            cache.Name = cacheItemName;
            cache.Callback = callbackMethod;
            cache.Cache = HttpRuntime.Cache;
            cache.LastRun = DateTime.Now;

            AddCacheObject(cache);

            return this;
        }
        /// <summary>
        /// Inserts the specified entry into the output cache.
        /// </summary>
        /// <param name="key">A unique identifier for <paramref name="entry"/>.</param>
        /// <param name="entry">The content to add to the output cache.</param>
        /// <param name="utcExpiry">The time and date on which the cached entry expires.</param>
        /// <returns>
        /// A reference to the specified provider.
        /// </returns>
        public override object Add(string key, object entry, DateTime utcExpiry)
        {
            DateTime universalTime = utcExpiry.ToUniversalTime();

            var cacheItem = new CacheItem
                {
                    Id = key,
                    DataType = entry.GetType(),
                    Item = SerializerHelper.Serialize(entry)
                };

            var now = DateTime.UtcNow;

            if (universalTime > DateTime.MinValue && universalTime > now && universalTime < DateTime.MaxValue)
                cacheItem.Expiration = universalTime;

            RedisClient redis = null;

            try
            {
                redis = !String.IsNullOrEmpty(_password) ? new RedisClient(_host, _port, _password) : new RedisClient(_host, _port);

                using (var trans = redis.CreateTransaction())
                {
                    CacheItem item = cacheItem;
                    trans.QueueCommand(r => r.Set(key, item));

                    if (cacheItem.Expiration.HasValue)
                        trans.QueueCommand(r => r.ExpireEntryAt(key, universalTime));

                    trans.Commit();
                }

                cacheItem = redis.Get<CacheItem>(key);
            }
            finally
            {
                if (redis != null)
                    redis.Dispose();
            }

            if (cacheItem == null || cacheItem.Item == null) return null;

            return SerializerHelper.Deserialize(cacheItem.Item);
        }
Ejemplo n.º 7
0
        private void AddCacheObject(CacheItem cacheItem)
        {
            var cacheExpirationInterval = Interval; // In minutes

            // ** If the specified cache interval is 0 minutes, do nothing, effectively disabling the timer
            if (cacheExpirationInterval == 0) { return; }

            if (Equals(cacheItem.Cache[cacheItem.Name], null))
            {
                cacheItem.Cache.Add(cacheItem.Name,
                                    cacheItem,
                                    null,
                                    DateTime.Now.AddMinutes(cacheExpirationInterval),
                                    Cache.NoSlidingExpiration,
                                    CacheItemPriority.NotRemovable,
                                    CacheCallback);
            }
        }
Ejemplo n.º 8
0
 // MUST be called with cache lock held
 void EnqueueTimedItem(CacheItem item)
 {
     UpdateTimerPeriod(item);
     timedItems.Enqueue(item);
 }
Ejemplo n.º 9
0
        public object Get(string key)
        {
            try {
                cacheLock.EnterUpgradeableReadLock();
                CacheItem it = cache [key];
                if (it == null)
                {
                    return(null);
                }

                if (it.Dependency != null && it.Dependency.HasChanged)
                {
                    try {
                        cacheLock.EnterWriteLock();
                        if (!NeedsUpdate(it, CacheItemUpdateReason.DependencyChanged, false))
                        {
                            Remove(it.Key, CacheItemRemovedReason.DependencyChanged, false, true);
                        }
                    } finally {
                        // See comment at the top of the file, above cacheLock declaration
                        cacheLock.ExitWriteLock();
                    }

                    return(null);
                }

                if (!DisableExpiration)
                {
                    if (it.SlidingExpiration != NoSlidingExpiration)
                    {
                        it.AbsoluteExpiration = DateTime.Now + it.SlidingExpiration;
                        // Cast to long is ok since we know that sliding expiration
                        // is less than 365 days (31536000000ms)
                        long remaining = (long)it.SlidingExpiration.TotalMilliseconds;
                        it.ExpiresAt = it.AbsoluteExpiration.Ticks;

                        if (expirationTimer != null && (expirationTimerPeriod == 0 || expirationTimerPeriod > remaining))
                        {
                            expirationTimerPeriod = remaining;
                            expirationTimer.Change(expirationTimerPeriod, expirationTimerPeriod);
                        }
                    }
                    else if (DateTime.Now >= it.AbsoluteExpiration)
                    {
                        try {
                            cacheLock.EnterWriteLock();
                            if (!NeedsUpdate(it, CacheItemUpdateReason.Expired, false))
                            {
                                Remove(key, CacheItemRemovedReason.Expired, false, true);
                            }
                        } finally {
                            // See comment at the top of the file, above cacheLock declaration
                            cacheLock.ExitWriteLock();
                        }

                        return(null);
                    }
                }

                return(it.Value);
            } finally {
                // See comment at the top of the file, above cacheLock declaration
                cacheLock.ExitUpgradeableReadLock();
            }
        }
Ejemplo n.º 10
0
		// MUST be called with cache lock held
		void EnqueueTimedItem (CacheItem item)
		{
			UpdateTimerPeriod (item);
			timedItems.Enqueue (item);
		}
Ejemplo n.º 11
0
		// MUST be called with cache lock held
		bool UpdateTimedItem (CacheItem item)
		{
			if (timedItems == null)
				return true;

			item.ExpiresAt = item.AbsoluteExpiration.Ticks;
			return !timedItems.Update (item);
		}
Ejemplo n.º 12
0
		void Insert (string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration,
			     CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback, CacheItemUpdateCallback onUpdateCallback, bool doLock)
		{
			if (key == null)
				throw new ArgumentNullException ("key");
			if (value == null)
				throw new ArgumentNullException ("value");
			if (slidingExpiration < TimeSpan.Zero || slidingExpiration > TimeSpan.FromDays (365))
				throw new ArgumentNullException ("slidingExpiration");
			if (absoluteExpiration != NoAbsoluteExpiration && slidingExpiration != NoSlidingExpiration)
				throw new ArgumentException ("Both absoluteExpiration and slidingExpiration are specified");
				
			CacheItem ci = new CacheItem ();
			ci.Value = value;
			ci.Key = key;
			
			if (dependencies != null) {
				ci.Dependency = dependencies;
				dependencies.DependencyChanged += new EventHandler (OnDependencyChanged);
				dependencies.SetCache (DependencyCache);
			}

			ci.Priority = priority;
			SetItemTimeout (ci, absoluteExpiration, slidingExpiration, onRemoveCallback, onUpdateCallback, key, doLock);
		}
        void WriteCacheData(CacheItem item, object entry)
        {
            string fileToWrite = GetFilePath(item);

            BinaryFormatter formatter = new BinaryFormatter();
            Stream destination = null;

            try
            {
                destination = new FileStream(fileToWrite, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
                formatter.Serialize(destination, entry);
            }
            catch (IOException)
            {

            }
            finally
            {
                if (destination != null)
                {
                    destination.Dispose();
                }
            }
        }
 void Remove(string key, CacheItem item)
 {
     RemoveCacheData(item);
     this.cacheItems.Remove(key);
 }
Ejemplo n.º 15
0
		void AddSequenceEntry (CacheItem item, EDSequenceEntryType type)
		{
#if DEBUG
			EDSequence.Add (new EDSequenceEntry (CopyItem (item), type));
#endif
		}
Ejemplo n.º 16
0
		public EDSequenceEntry (CacheItem item, EDSequenceEntryType type)
		{
			Type = type;
			Item = item;
		}
Ejemplo n.º 17
0
		public void OnItemDisable (CacheItem i)
		{
#if DEBUG
			CacheItem item;
			if (!items.TryGetValue (i.Guid, out item))
				return;

			EDSequence.Add (new EDSequenceEntry (CopyItem (i), EDSequenceEntryType.Disable));
#endif
		}
Ejemplo n.º 18
0
		string CreateNewCacheItemInstanceCode (string indent, CacheItem item)
		{
			var sb = new StringBuilder (indent + "new CacheItem {");
			sb.AppendFormat ("Key = \"{0}\", ", item.Key.Replace ("\n", "\\n").Replace ("\r", "\\r"));
			sb.AppendFormat ("AbsoluteExpiration = DateTime.Parse (\"{0}\"), ", item.AbsoluteExpiration.ToString ());
			sb.AppendFormat ("SlidingExpiration = TimeSpan.Parse (\"{0}\"), ", item.SlidingExpiration.ToString ());
			sb.AppendFormat ("Priority = CacheItemPriority.{0}, ", item.Priority);
			sb.AppendFormat ("LastChange = DateTime.Parse (\"{0}\"), ", item.LastChange.ToString ());
			sb.AppendFormat ("ExpiresAt = {0}, ", item.ExpiresAt);
			sb.AppendFormat ("Disabled = {0}, ", item.Disabled.ToString ().ToLowerInvariant ());
			sb.AppendFormat ("Guid = new Guid (\"{0}\")}}, \n", item.Guid.ToString ());

			return sb.ToString ();
		}
Ejemplo n.º 19
0
		static CacheItem CreateCacheItem (XPathNavigator node, Dictionary <Guid, int> cacheIndex, List <CacheItem> cacheItems)
		{
			Guid guid = node.GetRequiredAttribute <Guid> ("guid");
			int idx;

			if (cacheIndex.TryGetValue (guid, out idx))
				return cacheItems [idx];
			
			var ret = new CacheItem ();

			ret.Key = node.GetRequiredAttribute <string> ("key");
			ret.AbsoluteExpiration = node.GetRequiredAttribute <DateTime> ("absoluteExpiration");
			ret.SlidingExpiration = node.GetRequiredAttribute <TimeSpan> ("slidingExpiration");
			ret.Priority = node.GetRequiredAttribute <CacheItemPriority> ("priority");
			ret.LastChange = node.GetRequiredAttribute <DateTime> ("lastChange");
			ret.ExpiresAt = node.GetRequiredAttribute <long> ("expiresAt");
			ret.Disabled = node.GetRequiredAttribute <bool> ("disabled");
			ret.Guid = guid;

			cacheItems.Add (ret);
			cacheIndex.Add (guid, cacheItems.Count - 1);
			
			return ret;
		}		
Ejemplo n.º 20
0
		void SetItemTimeout (CacheItem ci, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemRemovedCallback onRemoveCallback,
				     CacheItemUpdateCallback onUpdateCallback, string key, bool doLock)
		{
			bool disableExpiration = DisableExpiration;

			if (!disableExpiration) {
				ci.SlidingExpiration = slidingExpiration;
				if (slidingExpiration != NoSlidingExpiration)
					ci.AbsoluteExpiration = DateTime.Now + slidingExpiration;
				else
					ci.AbsoluteExpiration = absoluteExpiration;			
			}
			
			ci.OnRemoveCallback = onRemoveCallback;
			ci.OnUpdateCallback = onUpdateCallback;
			
			try {
				if (doLock)
					cacheLock.EnterWriteLock ();
				
				if (ci.Timer != null) {
					ci.Timer.Dispose ();
					ci.Timer = null;
				}

				if (key != null)
					cache [key] = ci;
				
				ci.LastChange = DateTime.Now;
				if (!disableExpiration && ci.AbsoluteExpiration != NoAbsoluteExpiration)
					EnqueueTimedItem (ci);
			} finally {
				if (doLock) {
					// See comment at the top of the file, above cacheLock declaration
					cacheLock.ExitWriteLock ();
				}
			}
		}
        private object GetCacheData(CacheItem item)
        {
            string fileToRetrieve = GetFilePath(item);

            var formatter = new BinaryFormatter();
            Stream source = null;

            try
            {
                source = new FileStream(fileToRetrieve, FileMode.Open, FileAccess.Read, FileShare.Read);

                return formatter.Deserialize(source);
            }
            catch (IOException)
            {

            }
            finally
            {
                if (source != null)
                {
                    source.Dispose();
                }
            }

            return null;
        }
Ejemplo n.º 22
0
		CacheItem CopyItem (CacheItem item)
		{
			CacheItem newItem;

			if (items.TryGetValue (item.Guid, out newItem))
				return newItem;

			newItem = new CacheItem ();
			newItem.Key = item.Key;
			newItem.AbsoluteExpiration = item.AbsoluteExpiration;
			newItem.SlidingExpiration = item.SlidingExpiration;
			newItem.Priority = item.Priority;
			newItem.LastChange = item.LastChange;
			newItem.ExpiresAt = item.ExpiresAt;
			newItem.Disabled = item.Disabled;
			newItem.Guid = item.Guid;
			
			items.Add (newItem.Guid, newItem);
			
			return newItem;
		}
 string GetFilePath(CacheItem item)
 {
     return this.cacheFolder + item.FileName;
 }
Ejemplo n.º 24
0
 public EDSequenceEntry(CacheItem item, EDSequenceEntryType type)
 {
     Type = type;
     Item = item;
 }
        void RemoveCacheData(CacheItem item)
        {
            string fileToDelete = GetFilePath(item);

            try
            {
                File.Delete(fileToDelete);
            }
            catch (IOException) { }
        }
Ejemplo n.º 26
0
        void AddSequenceEntry(CacheItem item, EDSequenceEntryType type)
        {
#if DEBUG
            EDSequence.Add(new EDSequenceEntry(CopyItem(item), type));
#endif
        }
        public override void Set(string key, object entry, DateTime utcExpiry)
        {
            string filePath = GetFullPathForKey(key);
            var item = new CacheItem { Expiry = utcExpiry, Item = entry };

            using (var fileStream = File.OpenWrite(filePath))
            {
                var formatter = new BinaryFormatter();
                formatter.Serialize(fileStream, item);
            }
        }
Ejemplo n.º 28
0
        void SetItemTimeout(CacheItem ci, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemRemovedCallback onRemoveCallback,
                            CacheItemUpdateCallback onUpdateCallback, string key, bool doLock)
        {
            bool disableExpiration = DisableExpiration;

            if (!disableExpiration)
            {
                ci.SlidingExpiration = slidingExpiration;
                if (slidingExpiration != NoSlidingExpiration)
                {
                    ci.AbsoluteExpiration = DateTime.Now + slidingExpiration;
                }
                else
                {
                    ci.AbsoluteExpiration = absoluteExpiration;
                }
            }

            ci.OnRemoveCallback = onRemoveCallback;
            ci.OnUpdateCallback = onUpdateCallback;

            try {
                if (doLock)
                {
                    cacheLock.EnterWriteLock();
                }

                if (key != null)
                {
                    cache [key] = ci;
                    cache.EvictIfNecessary();
                }

                ci.LastChange = DateTime.Now;
                if (!disableExpiration && ci.AbsoluteExpiration != NoAbsoluteExpiration)
                {
                    bool enqueue;
                    if (ci.IsTimedItem)
                    {
                        enqueue = UpdateTimedItem(ci);
                        if (!enqueue)
                        {
                            UpdateTimerPeriod(ci);
                        }
                    }
                    else
                    {
                        enqueue = true;
                    }

                    if (enqueue)
                    {
                        ci.IsTimedItem = true;
                        EnqueueTimedItem(ci);
                    }
                }
            } finally {
                if (doLock)
                {
                    // See comment at the top of the file, above cacheLock declaration
                    cacheLock.ExitWriteLock();
                }
            }
        }
Ejemplo n.º 29
0
		void SetItemTimeout (CacheItem ci, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemRemovedCallback onRemoveCallback,
				     CacheItemUpdateCallback onUpdateCallback, string key, bool doLock)
		{
			bool disableExpiration = DisableExpiration;

			if (!disableExpiration) {
				ci.SlidingExpiration = slidingExpiration;
				if (slidingExpiration != NoSlidingExpiration)
					ci.AbsoluteExpiration = DateTime.Now + slidingExpiration;
				else
					ci.AbsoluteExpiration = absoluteExpiration;			
			}
			
			ci.OnRemoveCallback = onRemoveCallback;
			ci.OnUpdateCallback = onUpdateCallback;
			
			try {
				if (doLock)
					cacheLock.EnterWriteLock ();

				if (key != null) {
					cache [key] = ci;
					cache.EvictIfNecessary ();
				}
				
				ci.LastChange = DateTime.Now;
				if (!disableExpiration && ci.AbsoluteExpiration != NoAbsoluteExpiration) {
					bool enqueue;
					if (ci.IsTimedItem) {
						enqueue = UpdateTimedItem (ci);
						if (!enqueue)
							UpdateTimerPeriod (ci);
					} else
						enqueue = true;

					if (enqueue) {
						ci.IsTimedItem = true;
						EnqueueTimedItem (ci);
					}
					
				}
			} finally {
				if (doLock) {
					// See comment at the top of the file, above cacheLock declaration
					cacheLock.ExitWriteLock ();
				}
			}
		}
        private static CacheItem<object> GetCacheItem(string key, object entry, DateTime utcExpiry)
        {
            CacheItem<object> newItem;
            if (utcExpiry != default(DateTime) && utcExpiry != DateTime.MaxValue)
            {
                var timeout = TimeSpan.FromTicks(utcExpiry.Ticks - DateTime.UtcNow.Ticks);
                newItem = new CacheItem<object>(key, entry, ExpirationMode.Absolute, timeout);
            }
            else
            {
                newItem = new CacheItem<object>(key, entry);
            }

            return newItem;
        }
Ejemplo n.º 31
0
		// MUST be called with cache lock held
		void UpdateTimerPeriod (CacheItem item)
		{
			if (timedItems == null)
				timedItems = new CacheItemPriorityQueue ();

			long remaining = Math.Max (0, (long)(item.AbsoluteExpiration - DateTime.Now).TotalMilliseconds);
			item.ExpiresAt = item.AbsoluteExpiration.Ticks;
			
			if (remaining > 4294967294)
				// Maximum due time for timer
				// Item will expire properly anyway, as the timer will be
				// rescheduled for the item's expiration time once that item is
				// bubbled to the top of the priority queue.
				remaining = 4294967294;

			if (expirationTimer != null && expirationTimerPeriod <= remaining)
				return;
			expirationTimerPeriod = remaining;

			if (expirationTimer == null)
				expirationTimer = new Timer (new TimerCallback (ExpireItems), null, expirationTimerPeriod, expirationTimerPeriod);
			else
				expirationTimer.Change (expirationTimerPeriod, expirationTimerPeriod);
		}
Ejemplo n.º 32
0
		public void Enqueue (CacheItem item)
		{
			Queue.Push (item);
		}
Ejemplo n.º 33
0
		bool NeedsUpdate (CacheItem item, CacheItemUpdateReason reason, bool needLock)
		{
			try {
				if (needLock)
					cacheLock.EnterWriteLock ();
				
				if (item == null || item.OnUpdateCallback == null)
					return false;

				object expensiveObject;
				CacheDependency dependency;
				DateTime absoluteExpiration;
				TimeSpan slidingExpiration;
				string key = item.Key;
				CacheItemUpdateCallback updateCB = item.OnUpdateCallback;
				
				updateCB (key, reason, out expensiveObject, out dependency, out absoluteExpiration, out slidingExpiration);
				if (expensiveObject == null)
					return false;

				CacheItemPriority priority = item.Priority;
				CacheItemRemovedCallback removeCB = item.OnRemoveCallback;
				CacheItemRemovedReason whyRemoved;

				switch (reason) {
					case CacheItemUpdateReason.Expired:
						whyRemoved = CacheItemRemovedReason.Expired;
						break;

					case CacheItemUpdateReason.DependencyChanged:
						whyRemoved = CacheItemRemovedReason.DependencyChanged;
						break;

					default:
						whyRemoved = CacheItemRemovedReason.Removed;
						break;
				}
				
				Remove (key, whyRemoved, false, false);
				Insert (key, expensiveObject, dependency, absoluteExpiration, slidingExpiration, priority, removeCB, updateCB, false);
				
				return true;
			} catch (Exception) {
				return false;
			} finally {
				if (needLock) {
					// See comment at the top of the file, above cacheLock declaration
					cacheLock.ExitWriteLock ();
				}
			}
		}
        public override void Set(string key, object entry, DateTime utcExpiry)
        {
            // Do not cache any data if the user is logged in
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                return;
            }

            // Create a DiskOutputCacheItem object
            var item = new CacheItem(key, utcExpiry);

            WriteCacheData(item, entry);

            // Add item to CacheItems, if needed, or update the existing key, if it already exists
            this.cacheItems[key] = item;
        }
Ejemplo n.º 35
0
        /// <summary>
        /// Insert an object in cahce with key specified.
        /// </summary>
        /// <param name="key">key of the object.</param>
        /// <param name="value">Object to be inserted in cache.</param>
        public void Put(object key, object value)
        {
            try
            {
                if (key == null)
                    throw new ArgumentNullException("key", "null key not allowed");

                if (value == null)
                    throw new ArgumentNullException("value", "null value not allowed");

                string cacheKey = ConfigurationManager.Instance.GetCacheKey(key);

                Alachisoft.NCache.Web.Caching.CacheItem item = new Web.Caching.CacheItem(value);
                item.Priority = _regionConfig.CacheItemPriority;
               
                

                if (_regionConfig.ExpirationType.ToLower() == "sliding")
                    item.SlidingExpiration = new TimeSpan(0, 0, _regionConfig.ExpirationPeriod);
                else if (_regionConfig.ExpirationType.ToLower() == "absolute")
                    item.AbsoluteExpiration = DateTime.Now.AddSeconds(_regionConfig.ExpirationPeriod);


                    if (_logger.IsDebugEnabled)
                    {
                        _logger.Debug(String.Format("Inserting: key={0}&value={1}", key, value.ToString()));
                    }
                    _cacheHandler.Cache.Insert(cacheKey, item);
            }
            catch (Exception e)
            {
                if (_logger.IsErrorEnabled)
                {
                    _logger.Error("Put operation failed. " + e.Message);
                }
                throw new CacheException("Put operation failed. " + e.Message, e);
            }
        }
Ejemplo n.º 36
0
        void ExpireItems(object data)
        {
            DateTime  now  = DateTime.Now;
            CacheItem item = null;

            expirationTimer.Change(Timeout.Infinite, Timeout.Infinite);
            try {
                cacheLock.EnterWriteLock();
                while (true)
                {
                    item = timedItems.Peek();

                    if (item == null)
                    {
                        if (timedItems.Count == 0)
                        {
                            break;
                        }

                        timedItems.Dequeue();
                        continue;
                    }

                    if (!item.Disabled && item.ExpiresAt > now.Ticks)
                    {
                        break;
                    }

                    if (item.Disabled)
                    {
                        item = timedItems.Dequeue();
                        continue;
                    }

                    item = timedItems.Dequeue();
                    if (item != null)
                    {
                        if (!NeedsUpdate(item, CacheItemUpdateReason.Expired, false))
                        {
                            Remove(item.Key, CacheItemRemovedReason.Expired, false, true);
                        }
                    }
                }
            } finally {
                // See comment at the top of the file, above cacheLock declaration
                cacheLock.ExitWriteLock();
            }

            if (item != null)
            {
                long remaining = Math.Max(0, (long)(item.AbsoluteExpiration - now).TotalMilliseconds);
                if (remaining > 0 && (expirationTimerPeriod == 0 || expirationTimerPeriod > remaining))
                {
                    expirationTimerPeriod = remaining;
                    expirationTimer.Change(expirationTimerPeriod, expirationTimerPeriod);
                    return;
                }
                if (expirationTimerPeriod > 0)
                {
                    return;
                }
            }

            expirationTimer.Change(Timeout.Infinite, Timeout.Infinite);
            expirationTimerPeriod = 0;
        }