方法的缓存属性?

时间:2011-03-16 16:57:09

标签: c# .net asp.net caching

也许这是在做梦,但是有可能创建一个缓存函数输出的属性(例如,在HttpRuntime.Cache中)并从缓存中返回值而不是实际执行函数时函数的参数是一样的吗?

当我说功能时,我在谈论任何功能,它是否从数据库中提取数据,是否添加两个整数,或者它是否吐出文件的内容。任何功能。

6 个答案:

答案 0 :(得分:13)

你最好的选择是Postsharp。我不知道他们是否有你需要的东西,但这当然值得一试。顺便说一下,如果找到答案,请务必在此处公布答案。

编辑:另外,谷歌搜索“postharp缓存”提供了一些链接,如下所示:Caching with C#, AOP and PostSharp

更新:我最近偶然发现了这篇文章:Introducing Attribute Based Caching。如果您仍在寻找解决方案,它会在http://cache.codeplex.com/上描述基于postharp的库。

答案 1 :(得分:3)

我有同样的问题 - 我的应用程序中有多个昂贵的方法,我有必要缓存这些结果。前段时间我只是复制粘贴类似的代码,但后来我决定将这个逻辑从我的域中分解出来。 这就是我之前做过的事情:

    static List<News> _topNews = null;
    static DateTime _topNewsLastUpdateTime = DateTime.MinValue;
    const int CacheTime = 5;  // In minutes

    public IList<News> GetTopNews()
    {
        if (_topNewsLastUpdateTime.AddMinutes(CacheTime) < DateTime.Now)
        {
            _topNews = GetList(TopNewsCount);
        }

        return _topNews;
    }

这就是我现在可以写的方式:

    public IList<News> GetTopNews()
    {
        return Cacher.GetFromCache(() => GetList(TopNewsCount));
    }

Cacher - 是一个简单的帮助类,它是:

public static class Cacher
{
    const int CacheTime = 5;  // In minutes

    static Dictionary<long, CacheItem> _cachedResults = new Dictionary<long, CacheItem>();

    public static T GetFromCache<T>(Func<T> action)
    {
        long code = action.GetHashCode();

        if (!_cachedResults.ContainsKey(code))
        {
            lock (_cachedResults)
            {
                if (!_cachedResults.ContainsKey(code))
                {
                    _cachedResults.Add(code, new CacheItem { LastUpdateTime = DateTime.MinValue });
                }
            }
        }

        CacheItem item = _cachedResults[code];
        if (item.LastUpdateTime.AddMinutes(CacheTime) >= DateTime.Now)
        {
            return (T)item.Result;
        }

        T result = action();

        _cachedResults[code] = new CacheItem
        {
            LastUpdateTime = DateTime.Now,
            Result = result
        };

        return result;
    }
}


class CacheItem
{
    public DateTime LastUpdateTime { get; set; }
    public object Result { get; set; }
}

关于Cacher的几句话。你可能会注意到我在计算结果时不使用Monitor.Enter()(lock(...))。这是因为复制CacheItem指针(return(T)_cachedResults [code] .Result; line)是线程安全操作 - 它只执行一次笔划。如果多个线程同时更改此指针也是可以的 - 它们都将有效。

答案 2 :(得分:1)

您可以使用逗号分隔的字符串为您的类添加字典,其中包括函数名称作为键,结果作为值。然后,当您的函数可以检查字典中是否存在该值。将字典保存在缓存中,以便所有用户都可以使用。

答案 3 :(得分:1)

AFAIK,坦率地说,没有。

但是,这将是在框架内实施的一项承诺,以便它在所有情况下为所有人一般工作 - 无论如何 - 你可以通过简单的方式定制一些足以满足需求的东西(简单性与需求相关) ,显然)使用抽象,继承和现有的ASP.NET Cache

答案 4 :(得分:1)

PostSharp是你的一站式商店,如果你想创建一个[Cache]属性(或类似),你可以坚持任何方法。以前当我使用PostSharp时,我永远无法理解它的构建速度有多慢(这是在2007年,所以这可能不再相关了。)

另一种解决方案是将Render.Partial与ASP.NET MVC结合使用OutputCaching。这是为小部件/页面区域提供html的绝佳解决方案。

MVC的另一个解决方案是将[Cache]属性实现为ActionFilterAttribute。这将允许您采用控制器方法并将其标记为要缓存。它只适用于控制器方法,因为AOP魔法只能在MVC管道中与ActionFilterAttributes一起发生。

通过ActionFilterAttribute实施AOP已经发展成为我店铺的转型解决方案。

答案 5 :(得分:0)

如果您不需要属性配置但接受代码配置,那么您可能正在寻找MbCache吗?