Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用XmlDocument时内存不足_C#_Asp.net_Xmldocument - Fatal编程技术网

C# 使用XmlDocument时内存不足

C# 使用XmlDocument时内存不足,c#,asp.net,xmldocument,C#,Asp.net,Xmldocument,我有一个函数,它将生成一个数据集并从中创建一个xml文件。该功能工作正常。问题是,在多次运行报告后,我会出现“内存不足”错误。当我测试该报告时,我发现当它达到这个XmlDocument命令时,内存使用量会大大增加。 我用过GC,但没用,有什么建议吗 if (ddlDir.SelectedItem != null && ddlSec.SelectedItem != null) { using (DataSet dsClosedKPICalls = GetReportData

我有一个函数,它将生成一个数据集并从中创建一个xml文件。该功能工作正常。问题是,在多次运行报告后,我会出现“内存不足”错误。当我测试该报告时,我发现当它达到这个XmlDocument命令时,内存使用量会大大增加。 我用过GC,但没用,有什么建议吗

if (ddlDir.SelectedItem != null && ddlSec.SelectedItem != null)
{
    using (DataSet dsClosedKPICalls = GetReportData())
    {
        dsClosedKPICalls.DataSetName = "ClosedKPICalls";
        foreach (DataTable table in dsClosedKPICalls.Tables)
        {
            table.TableName = "ServiceInfo";
        }
        XmlContent = dsClosedKPICalls.GetXml();
    }

    XmlDocument XML_Data = new XmlDocument();           // contains the resultant XML data

    XML_Data.LoadXml(XmlContent);
    XmlNodeList TablesList = XML_Data.SelectNodes("ClosedKPICalls/ServiceInfo");

    for (int i = 0; i < TablesList.Count; i++)
    {
        XmlDocument innerXML = new XmlDocument();

        using (DataSet dsTaskDetails = getSplitupRecords(TablesList.Item(i).SelectSingleNode("ServiceNo").InnerText))
        {
            dsTaskDetails.DataSetName = "TaskDetails";
            foreach (DataTable tbl in dsTaskDetails.Tables)
            {
                tbl.TableName = "RequestInfo";
            }

            innerXML.LoadXml(dsTaskDetails.GetXml());

            TablesList.Item(i).AppendChild(XML_Data.ImportNode(innerXML.SelectSingleNode("TaskDetails"), true));

            innerXML = null;
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
    }
}
if(ddlDir.SelectedItem!=null&&ddlSec.SelectedItem!=null)
{
使用(数据集dsClosedKPICalls=GetReportData())
{
dsClosedKPICalls.DataSetName=“ClosedKPICalls”;
foreach(dsClosedKPICalls.Tables中的数据表)
{
table.TableName=“ServiceInfo”;
}
XmlContent=dsClosedKPICalls.GetXml();
}
XmlDocument XML_Data=new XmlDocument();//包含结果XML数据
XML_Data.LoadXml(XmlContent);
XmlNodeList tablelist=XML_Data.SelectNodes(“ClosedKPICalls/ServiceInfo”);
for(int i=0;i
您的XML文档有多大?具体来说,它们是否大于约85K

Net framework使用了一种称为的东西,它将用于大于~85K的分配。如果您的XML文档大于此值,则可能会在LOH中分配内容(如字符串)。LOH的问题在于它没有被压缩,因此它容易受到内存碎片的影响,这反过来会导致抛出
OutOfMemoryExceptions
,即使在进程正常情况下应该能够分配该内存时也是如此。这可能是您的问题的原因

对于解决方案,您可以尝试

  • 通过将对象的大小保持在85K以下来减少LOH的使用。这可能很难实现,具体取决于您的应用程序,但是可能(例如)将大型XML文档拆分为许多较小的文档
  • 尝试以.NETFrameworkV4.5为目标,看看这是否有帮助。.NETFrameworkV4.5包含了在这种情况下可能会有所帮助的功能

另一方面,对
GC.Collect
GC.WaitForPendingFinalizers
的调用是一个坏主意,因为这会人为地将较低代的对象升级到较高代,通常会“弄乱垃圾收集器”。在这种情况下,这些电话几乎肯定不会有帮助。一般来说,除非您确切地知道自己在做什么,否则您应该避免手动调用垃圾收集。

思考如何分割逻辑。您必须在一个块中处理所有表吗?您可以使用XmlTextWriter来减少内存占用吗?谢谢您的回复,您可以为我解释更多吗谢谢您的回复和解释,有没有其他方法可以不用xmlDocument阅读xml内容?@Noora是的,是一个只向前的xml阅读器,因此,它允许您逐节点读取XML,而无需将整个文档保存在内存中,缺点是使用起来要困难得多。您可以尝试从此读取器加载
XmlDocument
,而不是字符串—它可能是放置在LOH中的字符串(并导致您的问题),而不是
XmlDocument
内部的任何对象。