我正在使用HttpRuntime.Cache
來存儲將在整個會話中頻繁訪問的對象列表。將HttpRuntime.Cache項目讀取爲只讀
我用下面的代碼行從緩存中獲得該項目:
List<chartData_Type> _chartData =
(List<chartData_Type>)HttpRuntime.Cache.Get("rollingMonth");
但不幸的是,當我更新_chartData,它更新緩存項了。
如何獲取緩存項目的副本?
我正在使用HttpRuntime.Cache
來存儲將在整個會話中頻繁訪問的對象列表。將HttpRuntime.Cache項目讀取爲只讀
我用下面的代碼行從緩存中獲得該項目:
List<chartData_Type> _chartData =
(List<chartData_Type>)HttpRuntime.Cache.Get("rollingMonth");
但不幸的是,當我更新_chartData,它更新緩存項了。
如何獲取緩存項目的副本?
這是.NET的作品,因爲緩存只是參考指針的List
的方式。不知道你chartData_Type
是值類型還是引用類型。
如果值類型,很容易使用:
List<chartData_Type> list = new List<chartData_Type>(_chartData);
但是,如果引用類型,它涉及到複雜,你需要實現類DeepCopy方法,那麼對於每個對象做DeepCopy
名單。
DeepClone
方法:
public static class CloneHelper
{
public static T DeepClone<T>(T obj)
{
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
return (T) formatter.Deserialize(ms);
}
}
}
爲了使用這種方法,類chartData_Type
必須註明[Serializable]
:
[Serializable]
class chartData_Type
{}
所以,你可以手動做深克隆:
var cloneChartData = _chartData.Select(d =>
CloneHelper.DeepClone<chartData_Type>(d))
.ToList();
用途:
List<chartData_Type> list = new List<chartData_Type>(_chartData);
將所有項目複製從_chartData
到list
。
請注意,這將是對象的深層副本,因此您將不得不使用su請注意,緩存和此副本保持同步,否則...... OOOOOPS! –
也許有一點他的副本爲什麼要更新緩存版本的解釋。將得到我的投票= P –
列表是一個引用類型,_chartData保存存儲在緩存中的原始對象的地址。這就是爲什麼當你更新_chartData時,它也會更新緩存的對象。如果你想要一個單獨的對象,然後克隆緩存的對象。請參見下面的參考
http://www.codeproject.com/Articles/33364/ASP-NET-Runtime-Cache-Clone-Objects-to-Preserve-Ca
http://www.codeproject.com/Articles/45168/ASP-NET-Runtime-Cache-Clone-Objects-to-Preserve-Ca
我想知道AppFabric或NCache是否會解決這個問題。我在另一個線程中詢問了這個問題:http://stackoverflow.com/questions/23546817/appfabric-ncache-will-these-solve-httpruntime-cache-objects-being-updated-by-r – DrGriff