我有两个独立运行的.NET应用程序(可以以任何顺序启动,或者可能只运行一个),它使用XML作为数据存储。因此,两个应用程序都可以读写XML文件。 为了保持数据更新,我在读取和写入操作之前每次都从磁盘加载XML文件。我正在使用XPath查询来查询特定节点。 现在这个方法存在性能问题,因为每秒都有一个应用程序对XML进行读写请求(使用轮询,不能更改) 我不确定究竟是什么导致了性能损失,但我相信它的连续读写。
我尝试使用.NET 4.0中的内存映射文件,但我限制使用.NET 3.5而不是更高版本。
任何人都可以帮我解决这个问题吗?
注意:XML节点具有一些常用属性,不同数量的属性和一个用于XPath查询的ID。
答案 0 :(得分:3)
IF 您确定性能影响来自I / O而且您无法更改这两个应用程序,您可以做一些事情。
对现有应用程序代码零更改的第一个解决方案:使用RAM disk。如果他们将该文件用作共享内存,您可以在不进行任何其他更改的情况下执行此操作。如果数据是持久的,则可能需要在每次写入后对其他媒体执行后台复制。性能不如真正的共享内存好,但至少你不必等待缓慢的I / O操作。
仅在必须读取数据的应用程序中进行更改的第二个解决方案:通常解析XML文件的速度非常慢(特别是如果您使用XmlDocument
并且文件不是很少)。在这种情况下,使用XmlReader
,您必须使您的读取代码更复杂并忘记XPath查询,但其性能将比XmlDocument
好很多倍,并且不会减慢增加文件的速度大小
小(或不小)更新:如果可以更改第二个应用程序的代码(我猜是将读取文件的代码),您可以做一些改进其性能。首先不要每次都读取文件。检查其时间戳,为该文件或其他任何内容注册FileSystemWatcher
,但每次都不读取/解析文件。执行此操作时,您可以前进一步:只有在文件发生更改时才读取/解析文件,在后台(另一个线程)上准备XmlDocument
并使其可用于轮询请求。如果请求间隔,他们甚至可以看到非常快的响应时间(但是对于典型文件,XmlDocument
XPath查询的配置文件性能。)
编辑:here您可以找到Microsoft提供的RAM磁盘。它非常简单和天真,但通常你/我们不需要更多。此外,它是DDK上的一个示例,因此您也将获得源代码(在这种情况下......只是为了好玩)。
答案 1 :(得分:2)
XML不是为大量查询而设计的。如果需要这样做,请考虑使用数据库。 SQL Server Compact可能是一个不错的选择。如果您需要坚持使用XML并且需要使用大型文件并且需要性能,请考虑使用XmlReader / XmlWriter,它们不会将整个文件加载到内存中并且非常快。
答案 2 :(得分:2)
不是一直读取XML文件,而是第一次读取它,并获得文件的最后修改时间。
当您需要知道数据是否是最新的时,只需检查文件的修改时间,如果文件确实已更改,则只能再次读取该文件。
答案 3 :(得分:2)
不要轮询文件。读取一次并将其保留在内存中,然后在更改时使用FileSystemWatcher
仅重新加载 。
或者,读取修改时间戳,仅在时间戳更改时重新加载文件。
此外,在阅读文件时,请确保您非独占地锁定文件,以免其他读者被阻止。
答案 4 :(得分:1)
尝试专门打开文件。另一个应用程序可能会崩溃,但如果它没有崩溃,您肯定会知道一件事:它无法在共享文件的一个周期内调用太多的I / O负载,因为它的所有访问尝试都会立即失败。
希望它只需要等待一秒钟然后重试,这应该对你有用。
using (Stream iStream = File.Open("myfile.xml",
FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
...
}