垃圾回收在 Winforms 项目中过于激进



我继承了一个WinForms项目,并且遇到了一个奇怪的问题,我已经将其缩小为GC问题。我根本看不出它怎么会是其他任何东西,但请随时告诉我其他情况:-)

每隔几个月,应用程序就会运行一次。我无法定期重现它,但它已经发生在我的客户身上几次,我在我的开发人员环境中见过两次(但从来没有在我寻找它的时候)。

以下代码简化了设置。

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
{
}

我们最终处于应该不可能的状态,其中objB为空,但是我们的调试跟踪布尔值告诉我们它不应该是。

有没有人经历过这样的事情?关于该做什么或去哪里看的任何建议?

该项目是 .Net 4.0,在 32 位 XP 和 64 位 Windows 7 客户端计算机上已出现错误。

Smøller - WinForm 新手

你的问题出在你的二传手上,而不是在gc上:

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

setter/getter 不是线程安全的,如果你有多个线程同时访问 getter 和 setter,你可以得到一个位置,其中 _isBNull == null 和 _objB 是一个对象。

在查看您当前的代码时,我认为没有任何理由使用单独的属性_isBNull,您必须为此进行更改实际上取决于您对该类的功能要求。

相关内容

最新更新