XElement.ToString()引起了System.OutOfMemoryException异常。

3

我有一个包含大约120MB数据的对象。XML由大约6000个每个约20kb的元素组成。

我试图调用,因为我需要在Web服务中返回OuterXml。

我遇到了System.OutOfMemoryException异常。

System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
   at System.String.GetStringForStringBuilder(String value, Int32 startIndex, Int32 length, Int32 capacity)
   at System.Text.StringBuilder.GetNewString(String currentString, Int32 requiredLength)
   at System.Text.StringBuilder.Append(Char[] value, Int32 startIndex, Int32 charCount)
   at System.IO.StringWriter.Write(Char[] buffer, Int32 index, Int32 count)
   at System.Xml.XmlEncodedRawTextWriter.FlushBuffer()
   at System.Xml.XmlEncodedRawTextWriter.WriteAttributeTextBlock(Char* pSrc, Char* pSrcEnd)
   at System.Xml.XmlEncodedRawTextWriter.WriteString(String text)
   at System.Xml.XmlEncodedRawTextWriterIndent.WriteString(String text)
   at System.Xml.XmlWellFormedWriter.WriteString(String text)
   at System.Xml.XmlWriter.WriteAttributeString(String prefix, String localName, String ns, String value)
   at System.Xml.Linq.ElementWriter.WriteStartElement(XElement e)
   at System.Xml.Linq.ElementWriter.WriteElement(XElement e)
   at System.Xml.Linq.XElement.WriteTo(XmlWriter writer)
   at System.Xml.Linq.XNode.GetXmlString(SaveOptions o)
   at System.Xml.Linq.XNode.ToString()

我有同样的数据在一个XmlDocument中,并且可以调用XmlDocument.OuterXml而没有问题。我也可以调用XElement.Save()将XML保存到文件中而没有问题。

有人能否建议一种替代XElement.ToString()的方法,这种方法会减少内存占用?或者是我可以设置一些参数来允许更大的内存空间?


你需要通过 Web 服务返回 120MB 的数据... - Phill
那正是我所想的... - Mitch Wheat
尝试压缩数据并返回。 - TalentTuner
1
如果是针对内部系统,我仍然不会使用 Web 服务。如果网络上有任何负载,那么请求将被保持开放时间太长。为什么不能通过 FTP 在网络上传输它或将其放在共享目录中?或者使用其他不同于 HTTP 请求的方法。 - Phill
目前我无法更改第二个系统。 - Robin Day
显示剩余3条评论
2个回答

4

看起来你写入了太多的数据,一般情况下使用原始的 XmlWriter 可能是处理这样的数据量最好的选择。但是如果你可以成功地使用 Save() 方法,也可以尝试:

    string xml;
    using(var sw = new StringWriter()) {
        el.Save(sw);
        xml = sw.ToString();
    }

或者可能是:

    string xml;
    using (var ms = new MemoryStream()) { 
        using(var tw = new StreamWriter(ms, Encoding.UTF8))
        {
            el.Save(tw);            
        }
        xml = Encoding.UTF8.GetString(ms.GetBuffer(), 0, (int)ms.Length);
    }

但是这两个(或者其中一个)仍然可能会在火花中爆炸。您可能还想调查XStreamingElement,它专为这种情况而设计...但是,这是大量的xml - 特别是对于web服务来说。您是否愿意接受替代(更密集)序列化格式的建议?


0

我曾经遇到过同样的问题。

将 WCF 服务的 transferMode 设置为 StreamedStreamedResponse。同时,在 Web 服务器上启用压缩,可以将下载大小减小到原来的约10%。


我对 Web 服务没有问题。问题纯粹在于将 XElement 中的 XML 转换为字符串变量。 - Robin Day
@Robin Day:如果你进一步调查,你会发现你已经耗尽了Web服务器可用的内存。当我的响应达到大约120MB时,我开始看到同样的问题。你的服务器上有多少内存?我的是4GB,但我不确定增加更多内存是否有帮助。 - leppie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接