WeakReference 与 Disposed 的问题,怎样在运行时彻底销毁一个类实例?!

chinnel 2010-06-08 05:10:08
Winfrom 程序.
我用WeakReference做了个小缓存.用来缓存 自定义的控件(UserControl)
ControlsManager:

private static Dictionary<string, WeakReference> _store;
...
internal IControl GetControl(string name)
{
IControl control = null;
if (_store.ContainsKey(name))
{
control = _store[name].Target as IControl;
if (control == null)
{
control = CreateControl(name);
_store[name].Target = control;
}
}
else
{
control = CreateControl(name);
_store.Add(name, new WeakReference(control));
}
return control;
}

Form1:
private void toolStripButton2_Click(object sender, EventArgs e)
{
ControlsManager mgr = ControlsManager.Instance;
IControl ctr = mgr.GetControl("Listings");
this.Text = ctr.Name;
ctr.DisplayOn(panel1);
}

UserControl:
public partial class ucListings : UserControl,IControl
{
...
private void toolStripButton1_Click(object sender, EventArgs e)
{
_parent.Controls.Remove(this);
//问题:我这里Disposed了,并且我再执行了GC.Collect();
//但是这个玩意却依然存活在ControlsManager里相应的WeakReference中.
//为什么WeakReference依然保存着这个Control?是不是什么地方还有强引用?在哪儿?
//我怎样在这里完全释放掉这个Control?
this.Dispose();
}


问题在注释里面.
小弟分不多,跪求高人指点.
...全文
154 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
chinnel 2010-06-08
  • 打赏
  • 举报
回复
OK 我知道怎么做了.谢谢楼上几位.咳~ 钻牛角尖了.
chinnel 2010-06-08
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 vrhero 的回复:]
Dispose方法不是给托管对象用的,GC也不是你能操控的...GC.Collect只是通知GC可以回收,它有没有回收你管不着...

引用 MSDN:
GC.Collect 方法

无论对象在内存中的时间有多长,所有的对象均被考虑回收;不过,在托管代码中引用的对象不会被回收。使用此方法强制系统尝试回收最大可用内存量。

引用 MSDN:
使用弱引用的准则

......

……
[/Quote]

受教了.谢谢.
chinnel 2010-06-08
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 mrlen 的回复:]
惭愧,才学浅疏,这些代码我看不怎么出来。
你可以单独做一个弱引用示例试试。
[/Quote]

我下班的时候贴出来的,比较急了.代码有点凌乱,
我想想,
大概状况类似这样.
interface IControl{
void DisplayOn(Control container);
string Name{get;set;}
}
class ucListings : UserControl,IControl{
void Close(){base.Dispose();}
}
class ControlsManager{
static WeakReference cache;
static ControlsManager SingletonInstance{get;}
IControl GetControl(){
IControl ctr = new ucListings();
cache = new WealReference(ctr);
return ctr;
}
}
class Form1:Form{
void Foo(){
//这里的ctr 就是ucListings.
IControl ctr = ControlsManager.SingletonInstance.GetControl();
...//Do something here.
//这里使用完以后,ucListings中的Close()方法在其他地方被调用了.
//我希望销毁ucListings实例.
//接着调用GC.Collect();
//但是这个时候 ControlsManager 的cache中,仍然持有ucLitings的实例.就是不清楚哪个地方造成了强引用.只是由于曾经调用过Close(),也就是Dispose()方法,其中的components 变量被设为了null,其他的变量都没变.其实我觉得Dispose()这个问题,跟WeakReference没有关系.感觉就相当于:
ucListings uc = new ucListings();
uc.Dispose();
//这个地方仍然能取到值.郁闷!
string ucName = uc.Name;
  • 打赏
  • 举报
回复
例如msdn说的很清楚:“当不再使用托管对象时,垃圾回收器会自动释放分配给该对象的内存。但无法预测进行垃圾回收的时间。”。
  • 打赏
  • 举报
回复
谁跟你说过Dispose是彻底销毁对象你去找他算账!
「已注销」 2010-06-08
  • 打赏
  • 举报
回复
第二次 虽然重新实例化了一次,但是在任何其他地方都没有引用该类

整个程序
其实就是做了一个按钮的click
调用以下方法
第一次:
public void Run()
{
clsaa c = new class();
c.Dispose();
}

第二次

public void Run()
{
clsaa c = new class();
//c.Dispose();
}
vrhero 2010-06-08
  • 打赏
  • 举报
回复
Dispose方法不是给托管对象用的,GC也不是你能操控的...GC.Collect只是通知GC可以回收,它有没有回收你管不着...
[Quote=引用 MSDN:]
GC.Collect 方法

无论对象在内存中的时间有多长,所有的对象均被考虑回收;不过,在托管代码中引用的对象不会被回收。使用此方法强制系统尝试回收最大可用内存量。[/Quote]
[Quote=引用 MSDN:]
使用弱引用的准则

......

不应将弱引用作为内存管理问题的自动解决方案,而应开发一个有效的缓存策略来处理应用程序的对象。[/Quote]
「已注销」 2010-06-08
  • 打赏
  • 举报
回复
我只知道Dispose本身就不能"销毁"任何东西
他们都被放在垃圾回收器里

我以前做了一个实验,一个占用内存比较大的类.写一个Dispose方法
然后实例化之后Dispose掉

第一次
程序原本是15000内存.加载类后是21000,Dispose依然是21000左右(有一点点小的释放)
然后再次实例化类,此时,内存依然是21000

第二次
程序原本是15000内存.加载类后是21000,然后不Dispose,直接把类重新实例化一次
此时内存是26000左右

所以我的理解是Dispose之后并不是马上释放内存,只是可以在"有必要"的时候进行内存回收
颤菊大师 2010-06-08
  • 打赏
  • 举报
回复
惭愧,才学浅疏,这些代码我看不怎么出来。
你可以单独做一个弱引用示例试试。
xk1126 2010-06-08
  • 打赏
  • 举报
回复
还没学到asp.web帮顶!~~
chinnel 2010-06-08
  • 打赏
  • 举报
回复
继续等牛人出现.... 唉.凄凉~
chinnel 2010-06-08
  • 打赏
  • 举报
回复
都没人知道吗?!
为什么 UserControl 调用了Dispose(treu)后.
只是把Components(:IContainer) 设置成了null.
而UserControl本身并没有释放掉,里面的字段,什么的都还有效.
好像调用Dispose就是把心掏掉了,但是躯壳还在一样.
为什么?
有没有高人指点一下?!

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧