Действительно рекурсивный вызов.
pDoc.Save()
вызывает WriteTo(XmlWriter w)
на документе, который вызывает WriteContentTo(XmlWriter w)
.
Затем вызывается WriteTo(XmlWriter w)
на всех узлах корневого уровня, который будет содержать один узел элемента (возможно, также некоторые комментарии, пробелы, инструкции по обработке, декларацию документа ...).
На этом элементе это заставит его написать свой тег ('<', имя элемента, а затем любые атрибуты) с последующим вызовом <code>WriteContentTo(XmlWriter w), который вызывает WriteTo(XmlWriter w)
для каждого дочернего элемента, который вызывает WriteContentTo(XmlWriter w)
, и так далее и тому подобное.
Следовательно, это действительно рекурсивно в том, что каждый элемент вызывает один и тот же метод для своих дочерних элементов и с достаточно глубоким документом на достаточно маленьком пространстве стека (по умолчанию 1 МБ в большинстве приложений, но 256 КБ в ASP.NET), вы ' будет переполнение стека.
Для записи, вы также можете иметь переполнение стека без рекурсии, если вы прожигаете пространство стека так или иначе. stackalloc
- это отличный способ убедиться, что вы делаете это, пока всего несколько звонков.
Если у вас возникли проблемы из-за этой рекурсии, помните, что реализация WriteTo
по сути (вручную вставляя в нее WriteContentTo
):
w.WriteStartElement(this.Prefix, this.LocalName, this.NamespaceURI);
if (this.HasAttributes)
{
XmlAttributeCollection attributes = this.Attributes;
for (int i = 0; i < attributes.Count; i++)
{
attributes[i].WriteTo(w);
}
}
if (this.IsEmpty)
{
w.WriteEndElement();
}
else
{
for (XmlNode node = this.FirstChild; node != null; node = node.NextSibling)
{
node.WriteTo(w);
}
w.WriteFullEndElement();
}
Замените это итеративной версией, и вы не переполните стек. Конечно, если вам каким-то образом удалось поместить документ в состояние, в котором есть элемент, являющийся предком для него (защищает ли XmlDocument от этого? Я не знаю, как это происходит в моей голове), тогда он обернется переполнение стека в бесконечный цикл, который, если что-нибудь хуже.