Linq to Xml,保持XDocument加载

本文关键字:XDocument 加载 保持 to Xml Linq | 更新日期: 2023-09-27 18:14:48

假设我正在编写一个WinForms程序,它将在后台使用XML文档作为持久机制…

以下两种方法的优缺点是什么?

  1. 在每个方法调用中加载XDocument:

    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;
        }
    }
    

  1. 将XDocument保存在内存中…

    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;
        }
    }
    

Linq to Xml,保持XDocument加载

第一种方法似乎效率不高,因为每次访问XML文档时都加载它,没有任何好处。使用选项1,您必须先到磁盘,并在访问XML文件之前将其加载到内存中。在现代计算机上,读取磁盘是最昂贵的操作之一,应该尽量避免。

也就是说,如果XML文件太大,内存占用非常大,那么您可能希望只加载一小段时间。但是,如果内存占用非常大,那么您可能需要寻找另一种持久化数据的方法,这种方法不需要立即加载整个文档来进行修改。

这个平衡主要是在内存和文件系统访问之间——如果你打算在代码中大量使用文档,你不希望过多地与文件系统交互……但是如果它很少被访问并且很大,您可能不希望内存被占用。

我可能会默认将其保存在内存中-当它变得足够大,内存占用很重要时,您可能不想再使用XML了。

除了这些方面,在两种情况下,您都需要考虑特定应用程序所需的线程模型。

就像一点数据一样——我在c# in Depth网站上使用第二种模式来处理勘误表等,它工作得很好。

将文档存储在内存中的一个可能的缺点是,如果没有降级缓存,那么这些实例可能永远存在。这并不一定是一件可怕的事情,但这是你在设计时应该考虑的事情。

另外,如果文档很大,或者您有大量的小文档,那么缓存中的项数可能会导致内存问题。同样,您必须衡量这是否与您有关。

也就是说,您肯定会从缓存中获益;根据文档和访问它的频率,您不必重复地将文档处理为XDocument。如果文档很大,或者您要访问它们很多次,那么您就可以节省处理时间,因为您已经完成了一次,并且不需要再做一次。

基于文件的优点:-跨流程工作良好(如果需要)-保持持续的内存需求小(如果文件很大,比如超过10mb)基于文件的缺点:-每次操作加载速度较慢

基于内存的优点:-更快,没有一次又一次重新序列化的开销-更容易移植,如果你需要通过Web服务等访问文件。基于内存的缺点:-持续的内存需求(如果是大文件)

另一个想法,如果你已经有了XML格式的数据,为什么不直接使用它作为你的POCO对象,而是在你的"getfoo"方法中将它们重新序列化成对象