考虑以下代码,其中A类负责管理本机数据。指向该数据的指针被传递给B类,因此我需要在使用B时不收集A:
class A
{
public A(string n)
{
_n = n;
_p = IntPtr.Zero; //acquire native resource
}
public IntPtr GetP()
{
return _p;
}
~A()
{
Console.WriteLine("Free native resource {0}", _n);
}
string _n;
IntPtr _p;
};
class B
{
public B(IntPtr p)
{
_p = p;
}
public B(IntPtr p, Object o)
{
_p = p;
_o = o;
}
public IntPtr GetP()
{
return _p;
}
IntPtr _p;
Object _o;
};
如果我没有从'b'中引用'a','a'会立即按预期收集,这会留下指向无效数据的指针(至少在visual studio中,单声道中的gc是不那么急切:
static void Main(string[] args)
{
var a = new A("a");
var b = new B(a.GetP());
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("b._p: {0}", b.GetP());
}
Output:
Free native resource a
b._p: 0
但如果我从'b'中引用'a',那么'a'在退出之前不会被释放,即使以后没有使用'a':
static void Main(string[] args)
{
var a = new A("a");
var b = new B(a.GetP(), a);
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("b._p: {0}", b.GetP());
}
Output:
b._p: 0
Free native resource a
所以我的问题是:在第二种情况下,'a'保证规则是活着的,而'b'没有被收集,或者这种行为依赖于实现?如果是后者,我将如何保持活着?我见过几个类似的问题,但我没有找到明确的答案。
答案 0 :(得分:5)
所以我的问题是:在第二种情况下,'a'保证规格是活着的,而'b'没有被收集,
是。如果b
引用了a
且未收集,则也不会收集a
。