5

我有一个网页缓存一些查询字符串值 30 秒,这样它就不会收到重复的值。我正在使用以下课程:

public class MyCache   {

private static ObjectCache cache = MemoryCache.Default;

public MyCache() { }


public void Insert(string key, string value)
{

    CacheItemPolicy policy = new CacheItemPolicy();
    policy.Priority = CacheItemPriority.Default;
    policy.SlidingExpiration = new TimeSpan(0, 0, 30);
    policy.RemovedCallback = new CacheEntryRemovedCallback(this.Cacheremovedcallback);

    cache.Set(key, value, policy);
}

public bool Exists(string key)
{
    return cache.Contains(key);
}

public void Remove(string key)
{
    cache.Remove(key);
}

private void Cacheremovedcallback(CacheEntryRemovedArguments arguments)
{      
    FileLog.LogToFile("Cache item removed. Reason: " + arguments.RemovedReason.ToString() +  "; Item: [" +  arguments.CacheItem.Key + ", " + arguments.CacheItem.Value.ToString() + "]");         
}
 }

这已经工作了几个星期,然后突然缓存不再保留这些值。将项目插入缓存后,CacheRemoved 回调立即触发,我得到了删除的原因:CacheSpecificEviction 这是在带有 .NET 4.0 的 Windows Server 2008 SP1、IIS7.5 上运行的。在此期间,没有对操作系统或 IIS 应用任何更改。

有没有办法解决这个问题,如果没有,是否有更好的缓存解决方案可以在网页中使用?

先感谢您。

4

3 回答 3

1

查看MemoryCacheStore(应该是使用的默认存储MemoryCache.Default)的源代码,似乎CacheSpecificEviction只有在释放缓存时才调用带有参数的删除回调:

https://referencesource.microsoft.com/#System.Runtime.Caching/System/Caching/MemoryCacheStore.cs,230

环顾四周,确保您的缓存对象没有被意外处置。

于 2018-11-19T16:38:14.827 回答
0

我还发现,RemovedCallback如果您调用MemoryCache.Set现有项目,则会执行 - 因为.Set会覆盖缓存中的项目。

解决方法是使用.Add而不是.Set

尽管 OP 提到CacheSpecificEviction了这并没有回答他的问题,但以防万一有人遇到类似的问题并在搜索网络后登陆这个问题。

于 2020-06-16T22:01:18.297 回答
-1

试试这个:

policy.AbsoluteExpiration = DateTime.Now.AddSeconds(30);

这就是我使用缓存的方式:

public static class CacheHelper
{
    private static ObjectCache _cache;
    private const Double ChacheExpirationInMinutes = 10;

    /// <summary>
    /// Insert value into the cache using
    /// appropriate name/value pairs
    /// </summary>
    /// <typeparam name="T">Type of cached item</typeparam>
    /// <param name="entity">item cached</param>
    /// <param name="key">Name of item</param>
    public static void Add<T>(T entity, string key) where T : class
    {
        if (_cache == null)
        {
            _cache = MemoryCache.Default;
        }
        if (_cache.Contains(key))
            _cache.Remove(key);
        CacheItemPolicy cacheItemPolicy = new CacheItemPolicy();
        cacheItemPolicy.AbsoluteExpiration = DateTime.Now.AddMinutes(ChacheExpirationInMinutes);
        _cache.Set(key, entity, cacheItemPolicy);
    }

    /// <summary>
    /// Remove item from cache
    /// </summary>
    /// <param name="key">Name of cached item</param>
    public static void Clear(string key)
    {
        if (_cache == null)
        {
            _cache = MemoryCache.Default;
            return;
        }
        _cache.Remove(key);
    }

    /// <summary>
    /// Retrieve cached item
    /// </summary>
    /// <typeparam name="T">Type of cached item</typeparam>
    /// <param name="key">Name of cached item</param>
    /// <returns>Cached item as type</returns>
    public static T Get<T>(string key) where T : class
    {
        if (_cache == null)
        {
            _cache = MemoryCache.Default;
        }
        try
        {
            return (T)_cache.Get(key);
        }
        catch
        {
            return null;
        }
    }
}
于 2013-02-15T10:38:10.697 回答