4

Linq to Xml API が大好きです。私が今まで使った中で最も簡単なもの。

XmlReaderまた、非キャッシング リーダーであるtop が実装されていることも思い出しました。つまり、次のことを意味します。

var rdr = XmlReader.Create("path/to/huge_3Gb.xml");

...すぐに返されます(おそらく、せいぜいxmlヘッダーを読み取っただけです)。

ドキュメントXDocument.Load()は、実際に を使用していると記載されていXmlReader.Create()ます。

すべてのLinqと同様に、Linq2Xml で遅延実行動作が得られることを期待していました。
しかし、ファイルに触れるものに対して通常行うように、これを試しました:

using(var xdoc = XDocument.Load("file")){ ... }

と驚き!XDocument が実装されていないため、コンパイルされませんIDisposable

うーん、それは独特です!の使用が終わったら、ファイル ハンドルを解放するにはどうすればよいXDocumentですか?

そして、それは私に気づきました:XDocument.Load()メモリ内のXml全体を一度に消費するかもしれません(そしてすぐにファイルハンドルを閉じます)?

だから私は試しました:

var xdoc = XDocument.Load("path/to/huge_3Gb.xml");

そして待って、待って、そしてプロセスは言った:

Unhandled Exception: OutOfMemoryException.

そのため、Linq to Xml はほぼ完璧 (素晴らしい API) ですが、葉巻はありません (大きな Xml で使用する場合)。

</rant>

私の質問は次のとおりです。

  1. 何か不足していますか?Linq to Xmlを遅延して使用する方法はありますか?

  2. 前の質問の答えが「いいえ」の場合:

Linq to Xml API が、たとえば Linq to Objects と同様の遅延動作を持つことができない客観的な理由はありますか? 少なくともいくつかの操作 (たとえば、 forward-only で可能なことXmlReader) は遅延して実装できるように見えます。

...または、 Eric Lippertを引用して、このように実装されていません。

「誰もその機能を設計、指定、実装、テスト、文書化、出荷していないからです」?

4

1 に答える 1

6

実際、Linq to Xml は遅延実行を使用します。ただし、ファイルのデータではなく、メモリ内のデータをクエリします。ファイル、ストリーム、文字列からデータをロードしたり、ドキュメントを手動で作成したりできます。インメモリ ノード グラフがどのように構築されるかは問題ではありません。Linq to xml は、xml ツリー (つまり、オブジェクト グラフ) のメモリ内表現を照会するために使用されます。

これは、遅延実行が Linq to Xml でどのように機能するかを示すサンプルです。次のデータを持つオブジェクト グラフを含む XDocument があるとします。

<movies>
  <movie id="1" name="Avatar"/>
  <movie id="2" name="Doctor Who"/>
</movies>

この xml データのメモリ内表現をどのように作成するかは問題ではありません。例えば

 var xdoc = XDocument.Parse(xml_string);
 // or XDocument.Load(file_name);
 // or new XDocument(new XElement("movies"), ...)

次にクエリを定義します。

var query = xdoc.Descendants("movie");

ドキュメントに含まれるメモリ内の xml 表現を変更できます。

xdoc.Root.Add(new XElement("movie"), new XAttribute("id", 3));

次にクエリを実行します。

int moviesCount = query.Count(); // returns 3

ご覧のとおり、Linq to Xml は遅延実行を使用しますが、Linq to Objects と同様に機能します。メモリ内データはここでクエリされます。

: XDocument は IDisposable を実装しません。これは、ノード グラフが構築された後は管理されていないリソースを保持しないためです。

于 2013-10-18T11:14:10.230 に答える