Search Unity

Odd behaviour with ObservableCollection.

Discussion in 'Scripting' started by MaxPalmer, Dec 10, 2020.

  1. MaxPalmer

    MaxPalmer

    Joined:
    Mar 9, 2013
    Posts:
    27
    I'm seeing some strange behaviour with an ObservableCollection, which is a private member of a class. I'm adding an item to the collection and in the next line going into a method on the class which in the first line checks the collection count. As soon as I enter the method, the count in the collection changes. I've got one method hooked up to the collection changed event. That does not show an item being removed. I've got one place in my code where collection items are removed. That's not hit. The hash code for the collection before the call and inside the method is the same. What's going on?

    Tried restarting. Same result. This is with Unity 2019.1.7f1.

    Psuedocode:
    mycollection.Add(item); // Count goes from 0 to 1
    DoSomething();

    ...

    void DoSomething()
    {
    // Collection is now empty
    if (myCollection.Count<1)
    {
    }
     
  2. MaxPalmer

    MaxPalmer

    Joined:
    Mar 9, 2013
    Posts:
    27
    Update, also happens if I change the collection to a List. Whether the collection is modified on entry to the method seems to depend on the contents of the method. I can strip code out and then the collection is not modified on entry to the method. Feels like a Unity bug to me.
     
    Last edited: Dec 10, 2020
  3. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,981
    Sorry but we can't make any sense out of your question. Your pseudo code will work, 100%. There is for sure not a bug in the .NET / Mono standard class List (as you said it also happens with the normal List). Please don't start searching for issues or bug in others people code. The first thing you should think of when you encounter an error / bug is: What have I done wrong or what have I understood wrong. 99.99% of all errors you will ever encounter are the result of your own mistakes.

    From the description I try to stab in the dark and assume your class is inherited from another and you may have redefined / hidden the private field of a base class and now you have to versions of the same variable. However I won't go any further as this is not a guessing game. If you have a question / problem and need help with it, you need to provide more information, specifically: code. Have you actually tried debugging your code with the VS debugger and stepping through your code line by line?
     
  4. MaxPalmer

    MaxPalmer

    Joined:
    Mar 9, 2013
    Posts:
    27
    Bunny83, yes this all comes from stepping through my code with the debugger. Stepping into the class level method changes the contents of the class level collection - depending on the contents of the method. The debugger shows the collection size changing on entry to the method before any of the contents of the method is executed. As I have said, the contents of the method changes whether the collection is cleared or not on entry to the method - i.e. commenting out some of the code yet to be executed changes the behaviour on entry to the method.

    I completely agree with you that bugs are most likely to be in my code, not the framework or implementation of the framework. However, I have been using .NET since it first came out back in 2002, so have a reasonable level of coding experience.

    Stepping into this method clears the collection arcSites on entry:

    Code (CSharp):
    1.  
    2. void UpdateBeachLineBreakpoints(double xSweepLine)
    3. {
    4.        if (this.arcSites.Count < 2)
    5.             return;
    6.  
    7.       foreach (var bp in this.breakPoints)
    8.       {
    9.             bp.Update(xSweepLine);
    10.       }
    11. }
    12.  
    This version of the method does not result in the collection being cleared. I'm stepping into this call from an outer call in the debugger and have a watch on the arcSite collection.

    Code (CSharp):
    1.  
    2. void UpdateBeachLineBreakpoints(double xSweepLine)
    3. {
    4.        if (this.arcSites.Count < 2)
    5.             return;
    6. }
    7.  
    Now in the second case the compiler might just optimise away any code. I was just experimenting to see if the method contents changed the behaviour and it does.

    The class is an internal class and does not inherit from anything.
     
    Last edited: Dec 11, 2020
  5. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,981
    Well what you said just makes no sense ^^. Clearing a collection (no matter if it's an ObservableCollection, Collection or List, they all use a List internally) is not a one instruction operation. So it can not happen somehow inbetween your sequencial code unless you have other threads messing with your collection. A collection has to be cleared actively. The generic List class has a normal native array internally. When it's "cleared" it has to iterate through all elements, sets them to default and set the internal count to 0. So a List can not magically reset itself. You may replace the list somewhere, somehow. However without seeing the exact code we can't say anything else besides that it is very very very unlikely that Unity, .NET or Mono has anything to do with your issue. Is your "arcSites" variable private? Are you sure you have full control over the lifetime of the collection instance and you know who has access to the instance? If you use threads and you haven't throught about proper syncing we are out anyways ^^
     
  6. MaxPalmer

    MaxPalmer

    Joined:
    Mar 9, 2013
    Posts:
    27
    Yes, the variable is private. I agree it makes no sense but it is what is happening. There are no other threads (of mine) either.
     
  7. MaxPalmer

    MaxPalmer

    Joined:
    Mar 9, 2013
    Posts:
    27
    OK, problem has magically resolved itself. No code has changed and it now all works.
     
  8. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,092
    Problems don't magically resolve...
     
    Bunny83 likes this.
  9. MaxPalmer

    MaxPalmer

    Joined:
    Mar 9, 2013
    Posts:
    27
    ... well hope it doesn't come back. Tried it today and it's fine, yesterday it wasn't. PC normally is put into hibernation overnight, but the problem has gone. I did try a reboot the other day and the issue persisted across a reboot. Anyway it's now behaving fine.
     
  10. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,981