public void Set(string key, byte[] value, DistributedCacheEntryOptions options)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            Connect();

            SessionStateValue ssValue = new SessionStateValue();

            ssValue.Value = value;

            DateTime nowUtc = DateTime.UtcNow;

            ssValue.LastAccessTimeUtc = nowUtc;

            // No need to check stale or expired data when setting an absolute expiration.
            // Think of if as setting a new key/value pair. Expired data will always be cleaned up
            // when the CleanupExpiredData job runs.

            if (options.AbsoluteExpiration != null)
            {
                //LogDebug("Inserting against key [" + key + "] with absolute expiration: " +
                //         options.AbsoluteExpiration.Value.DateTime);
                DateTimeOffset dto = options.AbsoluteExpiration.Value;
                ssValue.ExpirationTimeUtc = dto.DateTime + dto.Offset;
            }

            // If AbsoluteExpiration and AbsoluteExpirationRelativeToNow are set, use the latter.
            if (options.AbsoluteExpirationRelativeToNow != null)
            {
                //LogDebug("Inserting against key [" + key + "] with absolute expiration: " +
                //         options.AbsoluteExpiration.Value.DateTime);
                TimeSpan ts = options.AbsoluteExpirationRelativeToNow.Value;
                ssValue.ExpirationTimeUtc = nowUtc + ts;
            }

            if (options.SlidingExpiration != null)
            {
                //LogDebug("Inserting against key [" + key + "] with absolute expiration: " +
                //         options.AbsoluteExpiration.Value.DateTime);
                ssValue.SpanUntilStale = options.SlidingExpiration.Value;
            }

            _region.PutByteArray(key, ssValue.ToByteArray());
            return;
        }
        public byte[] Get(string key)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            Connect();

            // Check for nonexistent key
            SessionStateValue ssValue = GetValueForKey(key);

            if (ssValue == null)
            {
                return(null);
            }

            // Check for expired key
            DateTime nowUtc = DateTime.UtcNow;

            if (ssValue.ExpirationTimeUtc != DateTime.MinValue && ssValue.ExpirationTimeUtc < nowUtc)
            {
                return(null);
            }

            // Check for stale key
            if (ssValue.SpanUntilStale != TimeSpan.Zero &&
                nowUtc > (ssValue.LastAccessTimeUtc + ssValue.SpanUntilStale))
            {
                return(null);
            }

            //LogDebug("Inserting against key [" + key + "] with absolute expiration: " +
            //         options.AbsoluteExpiration.Value.DateTime);

            // Update the times for sliding expirations
            if (ssValue.SpanUntilStale != TimeSpan.Zero)
            {
                ssValue.LastAccessTimeUtc = nowUtc;
                _region.PutByteArray(key, ssValue.ToByteArray());
            }

            return(ssValue.Value);
        }