2011-10-06 72 views
3

我在处理存储在缓存中的DataTable时看到了奇怪的行为。虽然它可能是设计。对缓存项目(DataTable)的.NET引用

该场景很简单。我将数据库查询的结果存储在DataTable中并将其放入该缓存中。在完成数据库查询或从缓存中获取结果后,我需要对其进行一些后处理(如添加列或排序)。似乎操作正在发生在缓存中的项目。所以当我从缓存中获取物品时,它必须抓住对它的引用?

代码

string CacheKey = "SearchData"; 
DataTable CachedResults = null; 
object CachedObject = Cache[CacheKey]; 
if (CachedObject is DataTable) { CachedResults = (DataTable)CachedObject; } 
if (CachedResults == null) 
{ 
    CachedResults = new DataTable(); 
    // Query the database and fill CachedResults 

    if (Cache[CacheKey] == null) 
    { 
    Cache.Add(CacheKey, CachedResults, null, DateTime.Now.AddMinutes(30), Cache.NoSlidingExpiration, CacheItemPriority.Low, null); 
    } 

} 

CachedResults.Columns.Add("NewColumn"); 

我想我的问题是,是CachedResults只是缓存项的参考?如果我想避免,我需要在DataTable上做一个副本?

非常感谢, Maleks

+0

您已经正确回答您自己的问题。是的,CacheResults只是对缓存项目的引用,而且您确实需要制作副本(DataTable.Copy)。 – Joe

回答

2

这实际上取决于底层的缓存供应商是什么。如果它是内存提供者,那么是的:你正在操纵一个对象的单一引用。这可能非常糟糕,因为DataTable不是线程安全的,而且会混淆使用它的其他代码。

但是,如果您正在使用类似sql-server的作为缓存的后端,它将序列化和反序列化。

就个人而言,我的建议因此:只缓存不可变数据,或者,如果你必须高速可变数据,不从缓存中得到,当它发生变异它

在您的具体情况中,是的:在提取后复制DataTable可以避免该问题。

+0

谢谢马克。出于兴趣,你会考虑可以缓存的可变数据吗? – Maleks

1

是的,它是对缓存项目的引用。我一直管理它的方式是,只要从缓存中检索它就立即复制,这样更改不会自动反映出来。

+0

谢谢你的答案! – Maleks