Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

(XmlSerializer related) Editor hangs after second play

Discussion in 'Editor & General Support' started by starstriker1, Aug 1, 2015.

  1. starstriker1

    starstriker1

    Joined:
    Jul 15, 2012
    Posts:
    38
    There is a problem in my project where, if certain scripts and objects are run, then I can play the scene once and return to the editor. However, if I attempt to play again, compile, or exit Unity, Unity will hang and I'll need to go to task manager to kill it. As you might imagine, having to force quit Unity after every play is an extremely obnoxious barrier in my workflow. An infuriating extra issue here is that it's not 100% consistent; most of the time I'll trigger the issue but occasionally it will just work without issues giving me a false positive in my debugging efforts, before lapsing back into bad behaviour.

    This behaviour has been occurring sporadically in this project for multiple versions of Unity, maybe as far back as Unity 4 (current Unity version is 5.1.1p4). This makes me inclined to think it isn't related to any specific version of the editor.

    I've done a search for previous advice for this specific set of symptoms, and the causes seem to be pretty varied. For some people, network objects and external plugins that haven't been cleaned up properly are the cause, presumably because the garbage collector is choking on the objects during the compile/play/exit step. Another answer indicated that a coroutine stalling on an uncomplete WWW call was the culprit. None of this really helps me; the only third party library in use is the Oculus SDK (and I've since disabled VR to no benefit), and I've already stripped out all of my networking.

    The log doesn't really say anything interesting. These are the last few lines:
    The traditional approach of "disable things until it starts working again" has only seen mixed success. I've been able to determine that creating my player object is causing the issue, but because the player object is so complicated and is referenced widely across my project (and the try/hang/force-quit loop is a slow way to narrow things down), I've been having a hell of a time narrowing it down from there.

    If I can't figure out a better approach for debugging this, then I'll have to continue guessing and testing until I've narrowed down the cause, but that's going to take a while and I'm nearly at my wits end with this. Does anyone know any causes for this "hang on second play" behaviour? Does anyone know a better way to narrow down the cause than turning things on and off in my project before sending them into the black box of the unity Editor?

    Thanks!
     
  2. starstriker1

    starstriker1

    Joined:
    Jul 15, 2012
    Posts:
    38
    I've dug further, and I've been able to track the problem down to an XmlSerializer.Deserialize call. If I remove that, then the second play will reliably occur. If I keep it, the second play seems to reliably hang the editor, with the last line in the log being "Begin MonoManager ReloadAssembly".

    Adding to the strangeness is that this isn't a problem when loading from Resources.
    Code (CSharp):
    1.     public static SchematicFile LoadFromAsset(TextAsset asset)
    2.     {
    3.         XmlSerializer writer = new XmlSerializer(typeof(SchematicFile));
    4.         using (StringReader reader = new StringReader(asset.text))
    5.         {
    6.             return writer.Deserialize(reader) as SchematicFile;
    7.         }
    8.     }
    The above code works fine, but the following causes the second play issue:

    Code (CSharp):
    1.  
    2.         XmlSerializer writer = new XmlSerializer(typeof(SchematicFile));
    3.         using (FileStream file = new FileStream(filePath, FileMode.Open))
    4.         {
    5.             schematic = writer.Deserialize(file) as SchematicFile;
    6.         }
    As does the following replacement for that code that uses a StringReader to make it more like the working segment
    Code (CSharp):
    1.         string fileText = System.IO.File.ReadAllText(filePath);
    2.        
    3.         XmlSerializer writer = new XmlSerializer(typeof(SchematicFile));
    4.        using (StringReader reader = new StringReader(fileText))
    5.         {
    6.             schematic = writer.Deserialize(reader) as SchematicFile;
    7.         }
    It seems like the only difference between the two scenarios is that the first only pulls from resources while the final two pull from external file paths. Maybe something from the file IO operations is lingering and tripping up Unity when it tries to reload the assembly?

    Does anyone have any clue what's going on here? This is very frustrating!
     
  3. starstriker1

    starstriker1

    Joined:
    Jul 15, 2012
    Posts:
    38
    After some more digging, I've found that if I remove the XmlArray and XmlArrayItem attributes from the List<> in my serialized class, the issue disappears.

    The serialized classes look like this. If line 18 is commented out (thereby preventing the deserializer from being able to recognize and deserialize the list elements) then I can play/compile/quit the editor without issues.

    I also found another way to prevent the issue from triggering; if I reduce the number of source files (below 14) it doesn't trigger. With 15 source files, I trigger the freeze again.

    My best guess at this point is that there's some sort of accumulated garbage that Mono doesn't like from parsing so many files (or maybe so many of the List elements?) I read that the XmlSerializer generates an assembly to read the type at runtime so I made sure to statically cache the XmlSerializer, but that didn't help. Anyone know what's going on?