Memory Leak using StreamReader and XmlSerializer

前端 未结 6 2060

I\'ve been googling for the past few hours and trying different things but can\'t seem to the bottom of this....

When I run this code, the memory usage continuously

6条回答
  •  无人共我
    2020-11-22 06:12

    I'm using a "cache" class to avoid instantiating xmlserializer each time you need to serialize something (also added a XmlCommentAttribute for adding comments to the serialized properties in the xml output), to me it works like sharm, hope help someone with this:

     public static class XmlSerializerCache
    {
        private static object Locker = new object();
        private static Dictionary SerializerCacheForUtils = new Dictionary();
    
        public static XmlSerializer GetSerializer()
        {
            return GetSerializer(null);
        }
        public static XmlSerializer GetSerializer(Type[] ExtraTypes)
        {
            return GetSerializer(typeof(T), ExtraTypes);
        }
        public static XmlSerializer GetSerializer(Type MainTypeForSerialization)
        {
            return GetSerializer(MainTypeForSerialization, null);
        }
        public static XmlSerializer GetSerializer(Type MainTypeForSerialization, Type[] ExtraTypes)
        {
            string Signature = MainTypeForSerialization.FullName;
            if (ExtraTypes != null)
            {
                foreach (Type Tp in ExtraTypes)
                    Signature += "-" + Tp.FullName;
            }
    
            XmlSerializer XmlEventSerializer;
            if (SerializerCacheForUtils.ContainsKey(Signature))
                XmlEventSerializer = SerializerCacheForUtils[Signature];
            else
            {
                if (ExtraTypes == null)
                    XmlEventSerializer = new XmlSerializer(MainTypeForSerialization);
                else
                    XmlEventSerializer = new XmlSerializer(MainTypeForSerialization, ExtraTypes);
    
                SerializerCacheForUtils.Add(Signature, XmlEventSerializer);
            }
            return XmlEventSerializer;
        }
    
        public static T Deserialize(XDocument XmlData)
        {
            return Deserialize(XmlData, null);
        }
        public static T Deserialize(XDocument XmlData, Type[] ExtraTypes)
        {
            lock (Locker)
            {
                T Result = default(T);
                try
                {
                    XmlReader XmlReader = XmlData.Root.CreateReader();
                    XmlSerializer Ser = GetSerializer(ExtraTypes);
                    Result = (T)Ser.Deserialize(XmlReader);
                    XmlReader.Dispose();
                    return Result;
                }
                catch (Exception Ex)
                {
                    throw new Exception("Could not deserialize to " + typeof(T).Name, Ex);
                }
            }
        }
        public static T Deserialize(string XmlData)
        {
            return Deserialize(XmlData, null);
        }
        public static T Deserialize(string XmlData, Type[] ExtraTypes)
        {
            lock (Locker)
            {
                T Result = default(T);
                try
                {
    
                    using (MemoryStream Stream = new MemoryStream())
                    {
                        using (StreamWriter Writer = new StreamWriter(Stream))
                        {
                            Writer.Write(XmlData);
                            Writer.Flush();
                            Stream.Position = 0;
                            XmlSerializer Ser = GetSerializer(ExtraTypes);
                            Result = (T)Ser.Deserialize(Stream);
                            Writer.Close();
                        }
                    }
                    return Result;
                }
                catch (Exception Ex)
                {
                    throw new Exception("Could not deserialize to " + typeof(T).Name, Ex);
                }
            }
        }
    
        public static XDocument Serialize(T Object)
        {
            return Serialize(Object, null);
        }
        public static XDocument Serialize(T Object, Type[] ExtraTypes)
        {
            lock (Locker)
            {
                XDocument Xml = null;
                try
                {
                    using (MemoryStream stream = new MemoryStream())
                    {
                        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                        ns.Add("", "");
    
                        using (StreamReader Reader = new StreamReader(stream))
                        {
                            XmlSerializer Serializer = GetSerializer(ExtraTypes);
                            var settings = new XmlWriterSettings { Indent = true };
                            using (var w = XmlWriter.Create(stream, settings))
                            {
                                Serializer.Serialize(w, Object, ns);
                                w.Flush();
                                stream.Position = 0;
                            }
                            Xml = XDocument.Load(Reader, LoadOptions.None);
    
                            foreach (XElement Ele in Xml.Root.Descendants())
                            {
                                PropertyInfo PI = typeof(T).GetProperty(Ele.Name.LocalName);
                                if (PI != null && PI.IsDefined(typeof(XmlCommentAttribute), false))
                                    Xml.AddFirst(new XComment(PI.Name + ": " + PI.GetCustomAttributes(typeof(XmlCommentAttribute), false).Cast().Single().Value));
                            }
    
                            Reader.Close();
                        }
                    }
                    return Xml;
                }
                catch (Exception Ex)
                {
                    throw new Exception("Could not serialize from " + typeof(T).Name + " to xml string", Ex);
                }
            }
        }
    }
    
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class XmlCommentAttribute : Attribute
    {
        public string Value { get; set; }
    }
    

提交回复
热议问题