首页 文章

将ASP.NET线程安全缓存对象与几乎只读对象一起使用

提问于
浏览
1

我正在使用缓存对象来保存XMLDocument对象 . 具体来说,代码是:

XmlDocument xDoc = new XmlDocument();
if (HttpRuntime.Cache.Get("AuthorizationXML") == null)
{
    string file = GetAuthorizationXmlFilePath();
    xDoc.Load(file);
    HttpRuntime.Cache.Insert("AuthorizationXML", xDoc, new CacheDependency(file));
}
else
{
    xDoc = (XmlDocument)HttpRuntime.Cache.Get("AuthorizationXML");
}

return xDoc;

无论如何,我的团队负责人建议,因为缓存对象是线程安全的,所以将它用于几乎只读的对象将是浪费,并且最好将缓存对象实现为应用程序对象上的单件自由线程对象 . 这句话听起来合法吗?线程安全是否意味着缓存对象是通过锁定实现的,它会降低系统的速度吗?只是从缓存中读取时甚至应用锁定?我很感激任何评论 .

1 回答

  • 1

    ASP.NET仅保证更改缓存中的项目时的线程安全性,但在更改缓存中保存的对象时不提供任何保证 . 因此,如果从缓存中检索的对象不是不可变的(=创建后无法更改),则ASP.NET缓存将无法保护您 .

    不可变的对象不应该被多个线程重用 . 将它存储在ASP.NET缓存或某个全局定义的变量中并不重要 . 在线程上重用可变对象是危险的,并且可能导致竞争条件,以防它们(意外地)改变 .

    当对象是不可变的时,存储它的位置并不重要,因为所有线程都可以使用它而没有任何危险 . 使用Cache或Global / Singleton的选择与对象的线程安全无关,因为两者都需要线程安全的对象,并且缓存的保证非常蹩脚,所以这对你没有帮助 .

    ASP.NET缓存允许您将项目保留在缓存中一段时间,而Singleton将(根据定义)保留在那里直到AppDomain死亡 . 因此,如果您需要每个AppDomain生命周期(通过使用 CacheDependency 与您的示例一起显示)多次刷新项目,那么除了Singleton之外的其他内容;例如ASP.NET缓存 .

相关问题