5

XML をデータ ストアとして使用する 2 つの .NET アプリケーションを独立して実行しています (任意の順序で開始することも、1 つだけ実行することもできます)。したがって、両方のアプリケーションが XML ファイルの読み取りと書き込みを行うことができます。データを最新の状態に保つために、読み取りおよび書き込み操作の前に毎回ディスクから XML ファイルをロードしています。そして、特定のノードを照会するために XPath クエリを使用しています。1 つのアプリケーション (ポーリングを使用し、変更することはできません) から毎秒 XML に対する読み取りおよび書き込み要求があるため、このメソッドでパフォーマンスの問題が観察されています。読み書き。

.NET 4.0 のメモリ マップ ファイルを使用しようとしましたが、.NET 3.5 の使用に制限されており、それ以降のバージョンは使用できません。

誰でもこれについて私を助けることができますか?

注 : XML ノードには、いくつかの共通の属性、異なる数の属性、および XPath クエリに使用する 1 つの ID があります。

4

5 に答える 5

3

パフォーマンスへの影響が I/O によるものであることが確実で、両方のアプリケーションを変更できない場合は、実際にできることはほとんどありません。

既存のアプリケーション コードをまったく変更しない最初のソリューション: RAM ディスクを使用します。そのファイルを共有メモリとして使用している場合は、他に変更を加えることなく実行できます。データが永続的である場合、書き込みごとに別のメディアへのバックグラウンド コピーを実行する必要がある場合があります。パフォーマンスは真の共有メモリほど良くはありませんが、少なくとも遅い I/O 操作を待つ必要はありません。

データを読み取る必要があるアプリケーションのみを変更する 2 番目のソリューション: 多くの場合、XML ファイルの解析は非常に遅くなります (特に、使用XmlDocumentしていてファイルが非常に小さい場合)。この場合、 を使用XmlReaderすると、読み取りコードをより複雑にし、XPath クエリを忘れる必要がありますが、パフォーマンスは何倍も向上XmlDocumentし、ファイル サイズが大きくなっても速度が低下することはありません。

小さな (またはそれほど小さくない) 更新: 2 番目のアプリケーション (ファイルを読み取るアプリケーションだと思います) のコードを変更できる場合は、そのパフォーマンスを改善するために少し行うことができます。まず第一に、毎回ファイルを読み取らないでください。タイムスタンプを確認し、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

ファイルを排他的に開いてみてください。他のアプリケーションがクラッシュする可能性がありますが、クラッシュしない場合は、1 つのことは確かです。共有ファイルの 1 サイクルで多くの I/O 負荷を呼び出すことはできません。これは、すべてのアクセス試行がすぐに失敗するためです。

うまくいけば、少し待ってから再試行するだけで、うまくいくはずです。

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