Smoller
Smoller

Reputation: 153

Garbage collection too agressive in a Winforms project

I have inherited a WinForms project and are having a weird problem which I have narrowed down to being a GC problem. I simply can’t see how it can be anything else, but feel free to tell me otherwise :-)

Once every few month the application acts up. I have not been able to reproduce it on a regular basis, but it has happened to my customer a few times, and twice I have seen it in my developer environment (but never when I were looking for it).

The setup is as simplified in the following code.

public class Main
{
  Main()
  {
    var listOfB = new List<ObjB>();
    var objB = new ObjB();
    listOfB.Add(objB);
    var objA = new ObjA(objB);

    // Do alot of stuff with listOfB and different lists of objA-like-objects.
    // Sometimes objA only exists as objects in a DataGrid

    // listOfB exists for a long time, while objA comes and goes..
  }
}

class ObjA
{
  private bool _isBNull;
  private ObjB _objB;

  public ObjA(ObjB objB)
  {
    _objB = objB;
    _isBNull = objB == null;
  }

  public ObjB ObjB
  {
    get
    {
      if (!_isBNull && _objB == null)
      {
        //
        // This should NEVER happen, but happens anyway :-(
        //

        // Do some logging and now that we 
        // know it CAN happen anyway we throw up...
      }
      return _objB;
    }
    set
    {
      _isBNull = value == null;
      _objB = value;
    }
  }
}

class ObjB
{
}

And we end up in the should-be-impossible condition where objB is null, but our debug-track-boolean tells us it shouldn't be.

Has anyone experienced something like this? Any suggestions on what to do or where to look?

The project is .Net 4.0, and the error has been seen on 32bit XP and 64bit Windows 7 client machines.

Smøller - a WinForm newbie

Upvotes: 0

Views: 107

Answers (1)

Peter
Peter

Reputation: 27944

Your problem is in your setter, not in the gc:

set
{
  _isBNull = value == null;
  _objB = value;
}

The setter/getter is not thread safe, if you have multiple threads accessing the getter and setter at the same time you can get a situaltion where _isBNull == null and _objB is an object.

When looking at your current code I do not see any reason to have a seperate property _isBNull, the change you have to make for fixing this really depends on your functional requirements for the class.

Upvotes: 5

Related Questions