Beispiel #1
0
        /// <summary>
        /// Remove item from cache by key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="raiseEvents">Indicates whether events should be raised.</param>
        /// <param name="action">The action that need to be executed in synchronization with the item cache removal.</param>
        /// <returns>The value indicating whether the item was removed.</returns>
        private bool RemoveItem(TKey key, bool raiseEvents, Action action = null)
        {
            // Try to get item, if there is no item by that key then return true to indicate that item was removed.
            var item = default(CacheStorageValueInfo <TValue>);

            if (!_dictionary.TryGetValue(key, out item))
            {
                return(true);
            }

            action?.Invoke();

            var cancel           = false;
            var expirationPolicy = item.ExpirationPolicy;

            if (raiseEvents)
            {
                var expiringEventArgs = new ExpiringEventArgs <TKey, TValue>(key, item.Value, expirationPolicy);
                Expiring.SafeInvoke(this, expiringEventArgs);

                cancel           = expiringEventArgs.Cancel;
                expirationPolicy = expiringEventArgs.ExpirationPolicy;
            }

            if (cancel)
            {
                if (expirationPolicy == null && _defaultExpirationPolicyInitCode != null)
                {
                    expirationPolicy = _defaultExpirationPolicyInitCode.Invoke();
                }

                _dictionary[key] = new CacheStorageValueInfo <TValue>(item.Value, expirationPolicy);

                return(false);
            }

            _dictionary.Remove(key);

            bool dispose = _disposeValuesOnRemoval;

            if (raiseEvents)
            {
                var expiredEventArgs = new ExpiredEventArgs <TKey, TValue>(key, item.Value, dispose);
                Expired.SafeInvoke(this, expiredEventArgs);

                dispose = expiredEventArgs.Dispose;
            }

            if (dispose)
            {
                item.DisposeValue();
            }

            return(true);
        }
Beispiel #2
0
        public TValue GetFromCacheOrFetch(TKey key, Func <TValue> code, ExpirationPolicy expirationPolicy, bool @override = false)
        {
            Argument.IsNotNull("key", key);
            Argument.IsNotNull("code", code);

            return(ExecuteInLock(key, () =>
            {
                TValue value;

                var containsKey = _dictionary.ContainsKey(key);
                if (!containsKey || @override)
                {
                    value = code.Invoke();
                    if (!ReferenceEquals(value, null) || _storeNullValues)
                    {
                        if (expirationPolicy == null && _defaultExpirationPolicyInitCode != null)
                        {
                            expirationPolicy = _defaultExpirationPolicyInitCode.Invoke();
                        }

                        var valueInfo = new CacheStorageValueInfo <TValue>(value, expirationPolicy);
                        lock (_syncObj)
                        {
                            _dictionary[key] = valueInfo;
                        }

                        if (valueInfo.CanExpire)
                        {
                            _checkForExpiredItems = true;
                        }

                        if (expirationPolicy != null)
                        {
                            if (_expirationTimer == null)
                            {
                                UpdateTimer();
                            }
                        }
                    }
                }
                else
                {
                    value = _dictionary[key].Value;
                }

                return value;
            }));
        }
Beispiel #3
0
        /// <summary>
        /// Adds a value to the cache associated with to a key asynchronously.
        /// <para />
        /// Note that this is a wrapper around <see cref="GetFromCacheOrFetch(TKey,System.Func{TValue},ExpirationPolicy,bool)"/>.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="code">The deferred initialization code of the value.</param>
        /// <param name="expirationPolicy">The expiration policy.</param>
        /// <param name="override">Indicates if the key exists the value will be overridden.</param>
        /// <returns>The instance initialized by the <paramref name="code" />.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="key" /> is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException">If <paramref name="code" /> is <c>null</c>.</exception>
        public async Task <TValue> GetFromCacheOrFetchAsync(TKey key, Func <Task <TValue> > code, ExpirationPolicy expirationPolicy, bool @override = false)
        {
            Argument.IsNotNull("key", key);
            Argument.IsNotNull("code", code);

            lock (GetLockByKey(key))
            {
                var containsKey = _dictionary.ContainsKey(key);
                if (containsKey && !@override)
                {
                    return(_dictionary[key].Value);
                }
            }

            var value = await code.Invoke();

            lock (GetLockByKey(key))
            {
                if (!ReferenceEquals(value, null) || _storeNullValues)
                {
                    if (expirationPolicy == null && _defaultExpirationPolicyInitCode != null)
                    {
                        expirationPolicy = _defaultExpirationPolicyInitCode.Invoke();
                    }

                    var valueInfo = new CacheStorageValueInfo <TValue>(value, expirationPolicy);
                    lock (_syncObj)
                    {
                        _dictionary[key] = valueInfo;
                    }

                    if (valueInfo.CanExpire)
                    {
                        _checkForExpiredItems = true;
                    }

                    if (expirationPolicy != null)
                    {
                        if (_expirationTimer == null)
                        {
                            UpdateTimer();
                        }
                    }
                }
            }

            return(value);
        }
Beispiel #4
0
        /// <summary>
        /// Adds a value to the cache associated with to a key asynchronously.
        /// <para />
        /// Note that this is a wrapper around <see cref="GetFromCacheOrFetch(TKey,System.Func{TValue},ExpirationPolicy,bool)"/>.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="code">The deferred initialization code of the value.</param>
        /// <param name="expirationPolicy">The expiration policy.</param>
        /// <param name="override">Indicates if the key exists the value will be overridden.</param>
        /// <returns>The instance initialized by the <paramref name="code" />.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="key" /> is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException">If <paramref name="code" /> is <c>null</c>.</exception>
        public Task <TValue> GetFromCacheOrFetchAsync(TKey key, Func <Task <TValue> > code, ExpirationPolicy expirationPolicy, bool @override = false)
        {
            Argument.IsNotNull("key", key);
            Argument.IsNotNull("code", code);

            return(ExecuteInLockAsync(key, async() =>
            {
                CacheStorageValueInfo <TValue> cacheStorageValueInfo;
                if (!@override && _dictionary.TryGetValue(key, out cacheStorageValueInfo))
                {
                    return cacheStorageValueInfo.Value;
                }

                var value = await code();

                if (!ReferenceEquals(value, null) || _storeNullValues)
                {
                    if (expirationPolicy == null && _defaultExpirationPolicyInitCode != null)
                    {
                        expirationPolicy = _defaultExpirationPolicyInitCode();
                    }

                    var valueInfo = new CacheStorageValueInfo <TValue>(value, expirationPolicy);
                    lock (_syncObj)
                    {
                        _dictionary[key] = valueInfo;
                    }

                    if (valueInfo.CanExpire)
                    {
                        _checkForExpiredItems = true;
                    }

                    if (expirationPolicy != null)
                    {
                        if (_expirationTimer == null)
                        {
                            UpdateTimer();
                        }
                    }
                }

                return value;
            }));
        }