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

时间:2012-02-01 15:29:38

标签: c# asp.net caching thread-safety

我使用缓存对象来保存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 个答案:

答案 0 :(得分:1)

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

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

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

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