Linq to Xml, keep XDocument loaded?

2019-07-03 11:05发布

Let's say I'm making a WinForms program that will use an XML document behind the scenes as a persistence mechanism...

What are the pros/cons to the two following approaches...

  1. Load the XDocument in each method call:

    public class XmlFoosRepository
    {
        string xmlFileName;
    
        public XmlFoosRepository(string xmlFileName)
        {
            this.xmlFileName = xmlFileName;
        }
    
        public int AddFoo(Foo foo)
        {
            var xDoc = XDocument.Load(xmlFileName); // Always call Load()
    
            // ...
    
            xDoc.Save(xmlFileName);
            return foo.ID;
        }    
    
        public IEnumerable<Foo> GetFoos()
        {
            var xDoc = XDocument.Load(xmlFileName); // Always call Load()
    
            // ...
    
            return foos;
        }
    }
    

or

  1. Keep the XDocument in memory...

    public class XmlFoosRepository
    {
        XDocument xDoc;
    
        public XmlFoosRepository(string xmlFileName)
        {
            xDoc = XDocument.Load(xmlFileName); // Now in memory
        }
    
        public int AddFoo(Foo foo)
        {
            // ...
    
            xDoc.Save(xmlFileName);
            return foo.ID;
        }
    
        public IEnumerable<Foo> GetFoos()
        {
            // ...
    
            return foos;
        }
    }
    

4条回答
Animai°情兽
2楼-- · 2019-07-03 11:19

A possible drawback of storing the documents in memory is that if you don't have a degrading cache, then those instances will potentially live forever. This isn't necessarily a horrible thing but it's something you should think about in your design.

Also, the number of items in the cache, if the documents are large, or you have a tremendous number of little documents, could cause memory issues. Again, you have to measure whether or not this is a concern for you.

That said, you definitely gain a benefit from the cache; depending on the document and how often you access it, you won't have to process the document into an XDocument repeatedly. If the documents are large, or you are accessing them many times, then you save on that processing time as you've done it once, and won't have to do it again.

查看更多
仙女界的扛把子
3楼-- · 2019-07-03 11:29

The first one just seems slightly inefficient as you gain nothing by loading the XML document every time you access it. With option 1 you have to go to disk, and load the XML file into memory, before accessing it. Going to the disk is one of the most costly operations you can perform with a modern computer, and should be avoided as much as possible.

That being said, if the XML file is that large that the memory footprint is incredibly significant then you may want to only have it loaded for small amounts of time. However, if the memory footprint is that large then you might want to look into a different way of persisting data that doesn't require you to load the whole document at once to make modifications.

查看更多
爷、活的狠高调
4楼-- · 2019-07-03 11:31

The balance is mostly between memory and file system access - if you're going to use the document a lot within your code, you don't want to be interacting with the file system more than you want... but if it's rarely accessed and huge, you may not want the memory hit.

I would probably default to keeping it in memory - by the time it gets sufficiently big that the memory hit is important, you may not want to use XML anyway.

Aside from these aspects, in both cases you will need to consider the threading model required by your particular application.

Just as one point of data - I use the second pattern on the C# in Depth web site for errata etc, and it works very well.

查看更多
叼着烟拽天下
5楼-- · 2019-07-03 11:33

File Based Pros: - Works well across processes (if required) - Keeps on-going memory requirements small (if the file is large, like over 10mb) File Based Cons: - Slower to load on each operation

Memory Based Pros: - Faster, no overhead to re-serialize again and again - Easier to port, if you need to access the file later via a Web Service, etc. Memory Based Cons: - On-going memory requirements (if large file)

Another thought, if you have your data in XML already, why not just use that as your POCO objects, instead re-serializing them into objects in your "GetFoos" method.

查看更多
登录 后发表回答