4

APIから100万以上のレコードを取得しています。ReadToEndプルは正常に機能しますが、文字列変数を入力しようとすると、メモリ不足の例外が発生します。

コードは次のとおりです。

        XDocument xmlDoc = new XDocument();

        HttpWebRequest client = (HttpWebRequest)WebRequest.Create(uri);
        client.Timeout = 2100000;//35 minutes
        WebResponse apiResponse = client.GetResponse();

        Stream receivedStream = apiResponse.GetResponseStream();
        StreamReader reader = new StreamReader(receivedStream);

        string s = reader.ReadToEnd();

スタックトレース:

at System.Text.StringBuilder.ToString()
at System.IO.StreamReader.ReadToEnd()
at MyApplication.DataBuilder.getDataFromAPICall(String uri) in
    c:\Users\RDESLONDE\Documents\Projects\MyApplication\MyApplication\DataBuilder.cs:line 578
at MyApplication.DataBuilder.GetDataFromAPIAsXDoc(String uri) in
c:\Users\RDESLONDE\Documents\Projects\MyApplication\MyApplication\DataBuilder.cs:line 543

これを回避するにはどうすればよいですか?

4

4 に答える 4

6

ファイルが環境に対して大きすぎるようです。大きなファイルの DOM のロードは、特に win32 プラットフォームを使用している場合に問題になる可能性があります (これが当てはまるかどうかは示されていません)。

XmlReader の速度とメモリ効率を XElement/Xnode などの利便性と組み合わせて、処理後に変換されたコンテンツを保存するために XStreamingElement を使用できます。これにより、大きなファイルのメモリ効率が大幅に向上します

擬似コードの例を次に示します。

    // use a XStreamingElement for writing
    var st = new XStreamingElement("root"); 
    using(var xr = new XmlTextReader(stream))
    {
        while (xr.Read())
        {
            // whatever you're interested in
            if (xr.NodeType == XmlNodeType.Element) 
            {
                var node = XNode.ReadFrom(xr) as XElement;
                if (node != null)
                {
                    ProcessNode(node);
                    st.Add(node);
                }
            }

        }
    }
    st.Save(outstream); // or st.WriteTo(xmlwriter);
于 2012-12-04T20:10:59.923 に答える
2

XMLReaderは、メモリが問題になる場合の方法です。また、最速です。

于 2012-12-05T23:18:51.650 に答える
1

残念ながら、コードは表示されませんでしたが、ファイル全体がメモリに読み込まれているようです。それはあなたが避ける必要があるものです。

全体をメモリにロードすることなく、ストリームを使用してファイルを処理できる場合に最適です。

于 2012-12-04T19:24:38.717 に答える