5

我在.NET 中创建了一个注册表类,它是一个单例。显然,这个单例的行为就像它保存在缓存中一样(单例对象对每个会话都可用)。这是我应该将此单例添加到缓存中的好习惯吗?+ 我是否需要注意 GetInstance() 函数的并发问题?

namespace Edu3.Business.Registry
{
    public class ExamDTORegistry
    {
        private static ExamDTORegistry instance;
        private Dictionary<int, ExamDTO> examDTODictionary;

        private ExamDTORegistry()
        {
            examDTODictionary = new Dictionary<int, ExamDTO>();
        }

        public static ExamDTORegistry GetInstance()
        {
            if (instance == null)
            {
                instance = new ExamDTORegistry();
            }
            return instance;
        }
    }
}
4

6 回答 6

6

好吧,您的 GetInstance 方法当然不是线程安全的 - 如果两个线程同时调用它,它们很可能最终得到两个不同的实例。如果有帮助,我有一个关于实现单例模式的页面。

您的代码是否依赖于单例?请记住,如果重新加载 AppDomain,无论如何您都会获得一个新实例。

不过,我并没有真正看到将对象放入缓存有什么好处。你有什么特别想的吗?

于 2008-11-19T14:38:42.870 回答
5

尽管它们存在于 GoF 单例中,但通常被认为是不好的做法。您是否有任何理由希望只拥有一个实例?

于 2008-11-19T14:39:32.963 回答
2

HttpContext.Cache 可用于所有会话,但缓存中的项目可以在过期或存在内存压力时从内存中删除。

HttpContext.Application 也可用于所有会话,并且是存储持久的、应用程序范围的对象的好地方。

由于您已经创建了一个单例并且它可以工作,我不明白为什么应该使用其中一个内置的单例集合,除非您需要 Cache 为您提供的额外功能。

于 2008-11-19T19:43:38.450 回答
0

不确定缓存是什么意思...如果您希望将其缓存(例如...将其保存在内存中,这样您就不必从某些数据存储中再次获取它),那么是的,您可以将其放入缓存,它将对所有用户都是全局的。会话意味着每个用户,所以我认为这不是你想要的。

于 2008-11-19T14:40:50.090 回答
0

我认为最初的问题谈到了哪个是首选。如果您有保持静态或本质上不可变的数据,那么 http 缓存或单例模式就很有意义。如果在应用程序启动时加载单例,则根本不存在“线程”问题。一旦单例就位,您将收到您请求的相同实例。我在实际实现中看到的很多问题是人们在没有充分考虑的情况下使用这两种方法。为什么要使不可变的配置数据过期?有一个客户端缓存了那里的数据并且仍然创建了 ADO DB 对象等,当他们最后一次检查它是否在缓存中时。实际上,这两种解决方案都适用于您,但要获得任何积极效果,请确保您使用缓存/单例。无论哪种情况,如果您的数据不可用,

于 2018-12-27T14:46:38.767 回答
-1

我会让它像:

私有静态只读 ExamDTORegistry 实例;

那么你不需要检查 NULL 和它的线程安全。

于 2009-02-12T17:12:42.133 回答