Пользовательский класс, вызывающий переполнение стека в XML-сериализаторе .NET - PullRequest
1 голос
/ 30 ноября 2011

Хорошо, пост становился слишком длинным и содержал слишком много самокоррекции, поэтому я переписываю его с самого начала.Если вы хотите прочитать обратно, проверьте журнал изменений.

Последняя версия кода может быть найдена здесь: http://pastebin.com/KMHVb5gA Я получаю переполнение в system.XML.dll по некоторым причинам;У него нет трассировки стека, и он просто останавливает выполнение.

Я понятия не имею, ПОЧЕМУ он переполняется, но я знаю, что это происходит после того, как я вызываю Save ()

            public bool save(string filename) //causes stack overflow when savenode is IEnumerable (and otherwise it does nothing).
            {
                XmlSerializer serializer = new XmlSerializer(typeof(List<savenode>));
                System.IO.FileStream fstream = new System.IO.FileStream(filename, System.IO.FileMode.OpenOrCreate);
                serializer.Serialize(fstream, innerdict);
                fstream.Flush();
                fstream.Close();
                return true;
            }

Я полностьюновичок в создании моих собственных классов IEnumerable, поэтому, если вы видите что-то явно неправильное, пожалуйста, дайте мне знать!

Код вызова выглядит следующим образом:

        Console.WriteLine("Commencing XML persistency test");
        CedLib.Persistence.XMLPersistenceDictionary.XMLPersistenceDictionary persistence = new CedLib.Persistence.XMLPersistenceDictionary.XMLPersistenceDictionary(logger); //Works!!
        persistence.Add("test", "testvaluefennecs");
        Console.WriteLine(persistence["test"].obj);
        foreach (var snode in persistence)
        {
            Console.Write("Contents: " + snode.obj);
        }
        persistence.save("test.xml");
        persistence.load("test.xml");
        if (persistence["test"].obj != "testvaluefennecs")
        {
            logger.logerror(new Exception("XML test failed!! Expected 'testvaluefennecs', got: " + persistence["test"].obj));
        }
        else
            Console.WriteLine("XML test success!");

И вывод выглядит так:

Commencing XML persistency test
[17:54:09] info: Initialized new XMLPersistence dictionary
New node: test
[17:54:09] Notice: Adding new dictionary item: test
testvaluefennecs
Contents: testvaluefennecs
Process is terminated due to StackOverflowException.

У кого-нибудь есть идеи?Любое предложение приветствуется!Я полностью застрял в этом!

[править] Только что нашел точную строку, по которой он переполняется, вот это:

XmlSerializer serializer = new XmlSerializer(typeof(List<savenode>));

Ответы [ 2 ]

1 голос
/ 30 ноября 2011

Хорошо, это ни в коем случае не является окончательным, но это может помочь ..

Это на самом деле умирает после: -

persistence.save("test.xml");

В: -

XmlSerializer serializer = new XmlSerializer(typeof(List<savenode>));

StackTrace:

...more...stackoverflow... 
System.Xml.dll!System.Xml.Serialization.TypeDesc.CheckSupported() Line 326  C#
System.Xml.dll!System.Xml.Serialization.TypeDesc.CheckSupported() Line 337 + 0xa bytes  C#
System.Xml.dll!System.Xml.Serialization.TypeDesc.CheckSupported() Line 337 + 0xa bytes  C#
System.Xml.dll!System.Xml.Serialization.TypeDesc.CheckSupported() Line 337 + 0xa bytes  C#
System.Xml.dll!System.Xml.Serialization.TypeDesc.CheckSupported() Line 337 + 0xa bytes  C#
System.Xml.dll!System.Xml.Serialization.TypeDesc.CheckSupported() Line 337 + 0xa bytes  C#
System.Xml.dll!System.Xml.Serialization.TypeDesc.CheckSupported() Line 337 + 0xa bytes  C#
System.Xml.dll!System.Xml.Serialization.TypeDesc.CheckSupported() Line 337 + 0xa bytes  C#
System.Xml.dll!System.Xml.Serialization.TypeDesc.CheckSupported() Line 337 + 0xa bytes  C#
System.Xml.dll!System.Xml.Serialization.TypeDesc.CheckSupported() Line 337 + 0xa bytes  C#
System.Xml.dll!System.Xml.Serialization.TypeDesc.CheckSupported() Line 337 + 0xa bytes  C#
System.Xml.dll!System.Xml.Serialization.TypeScope.GetTypeDesc(System.Type type, System.Reflection.MemberInfo source, bool directReference, bool throwOnError) Line 647  C#
System.Xml.dll!System.Xml.Serialization.ModelScope.GetTypeModel(System.Type type = {Name = Cannot evaluate expression because the code of the current method is optimized. FullName = Cannot evaluate expression because the code of the current method is optimized.}, bool directReference) Line 40 + 0x15 bytes  C#
System.Xml.dll!System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(System.Type type = {Name = Cannot evaluate expression because the code of the current method is optimized. FullName = Cannot evaluate expression because the code of the current method is optimized.}, System.Xml.Serialization.XmlRootAttribute root = null, string defaultNamespace = null) Line 159 + 0x23 bytes    C#
System.Xml.dll!System.Xml.Serialization.XmlSerializer.XmlSerializer(System.Type type = {Name = Cannot evaluate expression because the code of the current method is optimized. FullName = Cannot evaluate expression because the code of the current method is optimized.}, string defaultNamespace = null) Line 200 + 0x27 bytes   C#
System.Xml.dll!System.Xml.Serialization.XmlSerializer.XmlSerializer(System.Type type) Line 177  C#
ConsoleApplication4.exe!CedLib.Persistence.XMLPersistenceDictionary.XMLPersistenceDictionary.save(string filename = "test.xml") Line 139 + 0x25 bytes   C#

Я думаю, что это может быть вашей проблемой: -

Сериализация ArrayList и универсального списка

XmlSerializer не может сериализовать или десериализовать следующее:

Массивы ArrayList

Массивы Списка (Of T)

От: http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx

К сожалению, я не уверен, как вы можете это исправить ...

0 голосов
/ 03 декабря 2011

Я ПОЛУЧИЛ ЭТО!Мой друг указал мне на это, и я должен добавить, что JonB тоже очень помог!

Проблема в том, что savenode был IEnumerable.Я думал, что мне это нужно, но оказывается, что я не нуждаюсь!Причина, по которой сериализатор был переполнен, заключалась в том, что сделав savenode перечисляемым, он превратил List в массив списков (которые он не может сериализовать!)

Трюк заключался в том, чтобы просто снова сделать savenode не IEnumerable, и все работало!1005 *

Теперь, чтобы найти другие новые ошибки и устранить их за более короткий промежуток времени.Иногда быть программистом - все равно что играть супер-мальчишку;Вы застряли на одном уровне в течение ДНЕЙ, но когда вы, наконец, прибили его, вы разбудили соседей от своей радости.(ups lol)

Новая версия кода для тех, кто интересуется: http://pastebin.com/7xQUMAUn

Текущий код вызова, Рабочий:

        Console.WriteLine("Commencing XML persistency test");
        CedLib.Persistence.XMLPersistenceDictionary.XMLPersistenceDictionary persistence = new CedLib.Persistence.XMLPersistenceDictionary.XMLPersistenceDictionary(logger); //Works!!
        persistence.Add("test", "testvaluefennecs");
        persistence["test"].Add("test", "fennecs");
        Console.WriteLine(persistence["test"].obj);
        foreach (var snode in persistence)
        {
            Console.Write("Contents: " + snode.obj);
            foreach (var item in snode.childnodes)
            {
                Console.Write("Contents: " + snode.obj);
            }
        }
        Console.WriteLine("\nSaving dictionary");
        persistence.save("test.xml");
        persistence = null; Console.WriteLine("Nullified dictionary");
        persistence = new CedLib.Persistence.XMLPersistenceDictionary.XMLPersistenceDictionary();
        persistence.load("test.xml");
        Console.WriteLine("Loaded dictionary");
        if (persistence["test"].obj != "testvaluefennecs")
        {
            logger.logerror(new Exception("XML test failed!! Expected 'testvaluefennecs', got: " + persistence["test"].obj));
        }
        else
            Console.WriteLine("XML test success!");

Пусть код будет свы!

...