5

我有两个独立运行的 .NET 应用程序(可以按任何顺序启动,或者可能只运行一个),它们使用 XML 作为数据存储。所以这两个应用程序都可以读取和写入 XML 文件。为了保持数据更新,我每次在读写操作之前从磁盘加载 XML 文件。我正在使用 XPath 查询来查询特定节点。现在在这种方法中观察到了性能问题,因为每秒都有来自一个应用程序的 XML 读写请求(使用轮询,并且无法更改)我不确定究竟是什么导致了性能下降,但我相信它是连续的读写。

我尝试使用 .NET 4.0 中的内存映射文件,但我被限制使用 .NET 3.5 而不是任何更高版本。

谁能帮我解决这个问题?

注意:XML 节点有一些共同的属性、不同数量的属性和一个用于 XPath 查询的 ID。

4

5 回答 5

3

如果您确定性能影响来自 I/O,并且您无法更改这两个应用程序,那么您确实可以做一些事情。

对现有应用程序代码进行零更改的第一个解决方案:使用RAM 磁盘。如果他们将该文件用作共享内存,则无需任何其他更改即可执行此操作。如果数据是持久的,您可能需要在每次写入后执行后台复制到另一个媒体。性能不如真正的共享内存,但至少您不必等待缓慢的 I/O 操作。

第二种解决方案,仅在必须读取数据的应用程序中进行更改:通常 XML 文件的解析非常慢(特别是如果您正在使用XmlDocument并且文件不是很少)。在这种情况下,使用XmlReader,您必须使您的读取代码更加复杂并忘记 XPath 查询,但它的性能将比它好很多倍XmlDocument,并且不会减慢增加文件大小的速度。

小(或不那么小)更新:如果可以更改第二个应用程序(我猜是读取文件的那个)的代码,您可以做一些事情来提高其性能。首先不要每次都读取文件。检查其时间戳,FileSystemWatcher为该文件或其他任何内容注册一个,但不要每次都读取/解析文件。当您这样做时,您可以向前迈出一步:仅在文件更改时读取/解析文件,准备您XmlDocument的后台(另一个线程)并使其可用于轮询请求。如果请求是间隔的,他们甚至可能会看到非常快的响应时间(但XmlDocument对典型文件的 XPath 查询性能进行了概要分析)。

编辑在这里您可以找到 Microsoft 提供的 RAM 磁盘。这非常简单和天真,但通常你/我们不需要更多。此外,它是 DDK 上的一个示例,因此您也将获得源代码(在这种情况下......只是为了好玩)。

于 2012-06-10T19:50:42.567 回答
2

XML 不是为繁重的查询而设计的。如果您需要这样做,请考虑使用数据库。SQL Server Compact可能是一个不错的选择。如果您需要坚持使用 XML 并且需要处理大文件并且需要性能,请考虑使用XmlReader / XmlWriter,它们不会将整个文件加载到内存中并且速度非常快。

于 2012-06-10T19:47:48.620 回答
2

无需多次读取 XML 文件,只需第一次读取并获取文件的最后修改时间。

当您需要知道数据是否是最新的时,只需检查文件的修改时间,如果文件确实发生了变化,请再次读取文件。

于 2012-06-10T19:52:46.393 回答
2

不要轮询文件。读取一次并将其保存在内存中,然后FileSystemWatcher在更改时重新加载它。

或者,读取修改时间戳并仅在时间戳更改时重新加载文件。


此外,在读取文件时,请确保将其锁定为非排他性,以免阻止其他读取器。

于 2012-06-10T20:00:43.450 回答
1

尝试以独占方式打开文件。另一个应用程序可能会崩溃,但如果它没有崩溃,您肯定会知道一件事:它不能在一个周期内对共享文件调用太多 I/O 负载,因为它的所有访问尝试都会立即失败。

希望它会等待一秒钟然后重试,这对你来说应该很有效。

using (Stream iStream = File.Open("myfile.xml",
            FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
    ...
}
于 2012-06-10T19:47:45.597 回答