9

我正在我在 asp.net 应用程序中使用的类库中实现缓存。

我使用静态方法将缓存对象创建为单例模式来更新缓存,该方法实际上只是用我需要缓存的数据集合加载成员变量/属性(当然有一些锁定逻辑)。我认为这是一个不错的方法,因为我可以通过调用来访问我的数据

MyCacheObject.Instance.MyDataCollection

我正在创建一个新的缓存对象来存储由某个键分区的大量数据。我要说的是我正在创建一个新的缓存,但是这个缓存不会一次加载所有数据,而是为每个访问的键存储一个集合。

MyOtherCacheObject.Instance.MyOtherDataCollection(indexkey)

这次提出了关于垃圾收集的问题。由于我正在存储大量数据,如果它突然被 gc'ed 会不会是一种浪费?由于它只是一个单例模式,因此无法确保数据保留在缓存中。

所以我的问题是 - 实现缓存来处理这种情况的最佳做法是什么?我真的不喜欢一个非常复杂的解决方案,而且我知道 System.Web 中有缓存,但这似乎有点“离题”,因为这只是一个类库,或者你怎么看?

4

2 回答 2

9

在我看来,最好的解决方案应具有以下特点:

  • 使用平台提供的可用缓存服务,尽量避免自己编写。

  • 不将您的类库耦合到 System.Web,以使层保持一致。

  • 但是,如果类库在 ASP.NET 应用程序中运行,则解决方案不应该需要引入另一个缓存实现(例如,企业库缓存应用程序块),这需要额外的配置和设置。

因此,我将使用 IoC 策略,以允许类库根据其运行环境使用不同的缓存实现。

假设您将抽象缓存合约定义为:

public interface ICacheService 
{
    AddItem(...);
}

您可以提供基于 System.Web 的实现:

public AspNetBasedCacheService : ICacheService
{
    AddItem(...)
    {
        // Implementation that uses the HttpContext.Cache object
    }
 }

然后将该实现“发布”为单例。请注意,与原始方法的不同之处在于,单例只是对基于 ASP.NET 缓存服务的实现的引用,而不是完整的“缓存对象”。

public class CacheServiceProvider 
{
    public static ICacheService Instance {get; set;}

}

您必须通过执行延迟初始化或在应用程序启动时(在 中Global.asax.cs)来初始化缓存实现

并且每个域组件都可以在不知道它是基于 System.Web 实现的情况下使用已发布的缓存服务。

// inside your class library:
ICacheService cache = CacheServiceProvider.Instance;
cache.AddItem(...);

我同意这可能不是最简单的解决方案,但我的目标是在不牺牲代码解耦和灵活性的情况下利用 ASP.NET 缓存实现。

我希望我理解你的问题是正确的。

于 2008-10-01T06:59:10.850 回答
1

只要缓存仍然保留对数据的引用,数据就不会被垃圾收集。

另外,永远不要使用单例。

于 2008-10-01T06:40:51.363 回答