2011-10-06 73 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