加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

.Net Core MemoryCache PostEvictionCallback无法正常工作

发布时间:2020-12-16 07:13:30 所属栏目:asp.Net 来源:网络整理
导读:我在Microsoft.Extensions.Caching.Memory.MemoryCache中设置了具有滑动过期的缓存项. 我想在每次缓存项到期时触发回调,但在我查询缓存中过期的缓存项之前,不会触发回调. 这是代码: using System;using Microsoft.Extensions.Caching.Memory;namespace Memc
我在Microsoft.Extensions.Caching.Memory.MemoryCache中设置了具有滑动过期的缓存项.
我想在每次缓存项到期时触发回调,但在我查询缓存中过期的缓存项之前,不会触发回调.

这是代码:

using System;
using Microsoft.Extensions.Caching.Memory;

namespace Memcache
{
    public class Program
    {
        private static MemoryCache _cache;
        private static int _cacheExpSecs;

        public static void Main(string[] args)
        {
            _cache = new MemoryCache(new MemoryCacheOptions());
            _cacheExpSecs = 2;

            var cacheEntryOptions = new MemoryCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(_cacheExpSecs))
            .RegisterPostEvictionCallback(callback: EvictionCallback);

            _cache.Set(1,"One",cacheEntryOptions);
            _cache.Set(2,"Two",cacheEntryOptions);

            var autoEvent = new System.Threading.AutoResetEvent(false);

            System.Threading.Timer timer = new System.Threading.Timer(checkCache,autoEvent,1000,6000);

            Console.Read();
        }

        private static void checkCache(Object o)
        {
            if(_cache.Get(1)!=null)
            {
                Console.WriteLine(string.Format(@"checkCache: Cache with key {0} will be removed manually and will trigger the callback.",1));
                _cache.Remove(1);
            }
            else
            {
                Console.WriteLine(string.Format("checkCache: Cache with key {0} is expired.",1));
            }


            if(_cache.Get(2) != null)
            {
                Console.WriteLine(string.Format("checkCache: Cache with key {0} will expire in {1} seconds,but won't trigger the callback until we check it's value again.",2,_cacheExpSecs));
            }
            else
            {
                Console.WriteLine(string.Format("checkCache: Cache with key {0} is expired.",2));
            }

        }

        private static void EvictionCallback(object key,object value,EvictionReason reason,object state)
        {
            Console.WriteLine();
            Console.WriteLine("/*****************************************************/");
            Console.WriteLine(string.Format("/*  EvictionCallback: Cache with key {0} has expired.  */",key));
            Console.WriteLine("/*****************************************************/");
            Console.WriteLine();
        }
    }
}

解决方法

这种情况正在发生,因为在您查询该项目并检查到期时,该项目不会被逐出

(来自MemoryCacheStore.Get(MemoryCacheKey key)的来源)

internal MemoryCacheEntry Get(MemoryCacheKey key) {
        MemoryCacheEntry entry = _entries[key] as MemoryCacheEntry;
        // has it expired?
        if (entry != null && entry.UtcAbsExp <= DateTime.UtcNow) {
            Remove(key,entry,CacheEntryRemovedReason.Expired);
            entry = null;
        }
        // update outside of lock
        UpdateExpAndUsage(entry);
        return entry;
    }

或者由于记忆压力而在内部调用Trim()

(来自TrimInternal(int percent)的来源)

/*SNIP*/
        trimmedOrExpired = _expires.FlushExpiredItems(true);
        if (trimmedOrExpired < toTrim) {
            trimmed = _usage.FlushUnderUsedItems(toTrim - trimmedOrExpired);
            trimmedOrExpired += trimmed;
        }
/*SNIP*/

如果您的系统当前内存不足以触发修剪,那么唯一可以驱逐项目的时间是尝试检索它们的时间.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读