承接此篇
.NET最爽的就是背後有GC(Garbage Collection)罩著,想配置物件就配置物件(NEW),用完拍拍屁股就走了,等下就會有服務生來收碗盤了,多爽!
可是如果你點到的菜是XML Serializer,可能就沒辦法那麼幸運了,GC是不收這道菜的,亂點到最後...整個餐廳桌上都會是你之前吃剩的XML Serializer
GC無法自動回收XML Serializer,(原因,Dynamically Generated Assemblies段落),過於任性大量配置Serializer的話,記憶體可是會爆的
既然如此只能讓自己勤勞點,MSDN推薦的作法是,快取(Cache)住使用過的XML Serializer,每次欲利用XML Serializer時,統一向管理函式索取,若快取庫內沒有,則重新配置一個,若有,則取出既有的參考傳回,如此一來再利用時便不用重新配置,也就避免了潛在的記憶體洩漏問題了
參考以下程式碼:
- 函式原型:
- 引數 - 要序列化的物件型別(若物件是衍生自某基底型別,則透過陣列傳入具體衍生型別)
- 傳回值 - XML Serializer實例
- 視野(Scope): public static,視為工具函式(Utility)
class utilities
{
/// <summary>
/// Used to store key-serializer
/// </summary>
/// <returns></returns>
private static Hashtable __dictionary = new Hashtable();
/// <summary>
/// Generate key according to contents of type list
/// </summary>
/// <param name="typeList"></param>
/// <returns></returns>
protected static int generateKey(List<Type> typeList)
{
//hash code summarize
return typeList.Sum(__type => __type.GetHashCode());
}
/// <summary>
/// Always fetch serializer from this function
/// (Never allocate by yourself)
/// </summary>
/// <param name="mainType"></param>
/// <param name="extraTypes"></param>
/// <returns></returns>
public static XmlSerializer getSerializer(Type mainType,Type[] extraTypes){
//merge the list
List<Type> __typeList = new List<Type>();
__typeList.Add(mainType);
__typeList.AddRange(extraTypes);
var key = generateKey(__typeList);
if (__dictionary.ContainsKey(key))
{
// this kind of serializer had been cached/used before ,
// get the cached serializer
return (XmlSerializer)__dictionary[key];
}
else
{
// never been used , need to create a new one and push into cache
XmlSerializer __serializer = new XmlSerializer(mainType,extraTypes);
__dictionary.Add(key,__serializer);
return __serializer;
}
}//getserializer
}//utilities
參考程式碼:https://github.com/smandyscom/cached_xmlSerializer
沒有留言:
張貼留言