WPF,这个对象没有自动销毁吗? 自定义控件MyControl中,设置了一个定时器因为你的定时器是设置在控件中的,所以无法回收而且你其实开了2个定时器 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 要想控件能够被回收,你的控件必须没有任何地方引用它任何地方,至少包含以下3个地方1.没有变量对它强引用2.没有添加到窗体控件容器中3.没有任何事件会去不断调用里面的方法你现在的问题就是3在保持对它的引用,timer回调事件不停的去执行实例中的方法,导致实例无法被回收 以上3的说法其实有点错误其实是你的控件里new了一个timer,而这个timer一直在工作,在timer被回收之前,控件本身也无法被回收除非控件里的对象都被回收,控件自身才有可能被回收 是你的控件还没来得及回收,你可以在不用的时候禁用timer 那如果MyControl控件中没有定时器,那new第二个MyControl的时候,第一个MyControl是不是立即被销毁了呢?销毁与否跟计时器有关系吗? 我测试了一下,至少在1分钟之内,是不断弹出"MyControl1"、"MyControl2"的,分钟之后,我就没测试了,还不知道会不会继续弹出"MyControl1"、"MyControl2"。如果是控件还没来得及回收,难道说这么长的时间,都还没有回收吗?甚至有可能是一直都不会回收.... 我测试了一下,至少在1分钟之内,是不断弹出"MyControl1"、"MyControl2"的,分钟之后,我就没测试了,还不知道会不会继续弹出"MyControl1"、"MyControl2"。如果是控件还没来得及回收,难道说这么长的时间,都还没有回收吗?甚至有可能是一直都不会回收.... 那如果MyControl控件中没有定时器,那new第二个MyControl的时候,第一个MyControl是不是立即被销毁了呢?销毁与否跟计时器有关系吗?不会立即回收,GC会负责定期,或内存吃紧的时候,回收.前提是我在3楼说的,没有地方引用这个东西,GC判断它已经没用了,才会被回收你的控件里有个timer一直在工作,GC怎么知道你到底是想让它工作还是不想让它工作了? 这个跟DispatcherTimer的实现有关系。1、DispatcherTimer触发的事件需要发生在UI线程上。2、因此,它使用了Dispatcher.CurrentDispatcher来运行触发过程,并在Start中把自己添加到Dispatcher.CurrentDispatcher中去。3、就是说Dispatcher.CurrentDispatcher引用了DispatcherTimer。4、而DispatcherTimer.Tick引用了MyControl的成员函数timer_Tick。5、成员函数delegate引用了MyControl实例对象。Dispatcher.CurrentDispatcher(属于当前的UI线程 )不会被回收,它引用的DispatcherTimer就不会被回收,DispatcherTimer引用的MyControl就不会被回收。注:上述第2点可以参考源代码(目前是第287行),而DispatcherTimer.Stop则会把自己同Dispatcher.CurrentDispatcher断开。http://referencesource.microsoft.com/#WindowsBase/src/Base/System/Windows/Threading/DispatcherTimer.cs 所以如果你的窗口关闭了,不用担心timer不会被回收,也不需要在关闭前手动将timer停止 你在给Content 赋值之前应该先判断其值是否为空,如果不为空就先停止timer,然后再重新赋值 private void button2_Click(object sender, RoutedEventArgs e) { MyControl mc = button2.Content as MyControl; if (mc == null) { button2.Content = new MyControl() { Name = "MyControl1" }; } else { mc.timer.Stop(); button2.Content = new MyControl() { Name = "MyControl1" }; } mc = button2.Content as MyControl; if (mc == null) { button2.Content = new MyControl() { Name = "MyControl2" }; } else { mc.timer.Stop(); button2.Content = new MyControl() { Name = "MyControl2" }; } } } public class MyControl : Control { public DispatcherTimer timer = new DispatcherTimer(); static MyControl() { DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(typeof(MyControl))); } public MyControl() { timer.Interval = new TimeSpan(0, 0, 2); timer.Tick += new EventHandler(timer_Tick); timer.Start(); } private void timer_Tick(object sender, EventArgs e) { MessageBox.Show(this.Name); } }自己把代码简化一下 .net的回收不具备即时性,也就是说你可以调用dispose()方法把对象标记为无效引用的对象,然后由GC来回收,但是什么时候回收却是由回收机制决定的 那你13楼写的代码,可不可以不写呢,在new新的MyControl之前,直接将先前的MyControl调用dispose()方法,这样就Timer就不会再运行了吧,更简洁吧 那你13楼写的代码,可不可以不写呢,在new新的MyControl之前,直接将先前的MyControl调用dispose()方法,这样不就回收了吗,更简洁吧 C#初等问题,在练习if语句时,为什么我运行不显示控制台,也没有报错。 程序打包的问题 c# Regex.Match 网页对话框?? 怎么解决校正倒计时? 急求sharepoint2003的webpart的教程,C#的 急求!!!!! C#程序和Sqlserver的安装部署 导出Excel时,保存地址弹出窗体可以选择求大神 请问如何发出信息,在另外的机器上接收,并显示出来? sign什么意思?? c# 服务器控件 radiobutton 新手请教 一个正则表达式
任何地方,至少包含以下3个地方
1.没有变量对它强引用
2.没有添加到窗体控件容器中
3.没有任何事件会去不断调用里面的方法
你现在的问题就是3在保持对它的引用,timer回调事件不停的去执行实例中的方法,导致实例无法被回收
其实是你的控件里new了一个timer,而这个timer一直在工作,在timer被回收之前,控件本身也无法被回收
除非控件里的对象都被回收,控件自身才有可能被回收
如果是控件还没来得及回收,难道说这么长的时间,都还没有回收吗?甚至有可能是一直都不会回收....
如果是控件还没来得及回收,难道说这么长的时间,都还没有回收吗?甚至有可能是一直都不会回收....
不会立即回收,GC会负责定期,或内存吃紧的时候,回收.
前提是我在3楼说的,没有地方引用这个东西,GC判断它已经没用了,才会被回收
你的控件里有个timer一直在工作,GC怎么知道你到底是想让它工作还是不想让它工作了?
2、因此,它使用了Dispatcher.CurrentDispatcher来运行触发过程,并在Start中把自己添加到Dispatcher.CurrentDispatcher中去。
3、就是说Dispatcher.CurrentDispatcher引用了DispatcherTimer。
4、而DispatcherTimer.Tick引用了MyControl的成员函数timer_Tick。
5、成员函数delegate引用了MyControl实例对象。Dispatcher.CurrentDispatcher(属于当前的UI线程 )不会被回收,它引用的DispatcherTimer就不会被回收,DispatcherTimer引用的MyControl就不会被回收。注:上述第2点可以参考源代码(目前是第287行),而DispatcherTimer.Stop则会把自己同Dispatcher.CurrentDispatcher断开。
http://referencesource.microsoft.com/#WindowsBase/src/Base/System/Windows/Threading/DispatcherTimer.cs
{
MyControl mc = button2.Content as MyControl;
if (mc == null)
{
button2.Content = new MyControl() { Name = "MyControl1" };
}
else
{
mc.timer.Stop();
button2.Content = new MyControl() { Name = "MyControl1" };
} mc = button2.Content as MyControl;
if (mc == null)
{
button2.Content = new MyControl() { Name = "MyControl2" };
}
else
{
mc.timer.Stop();
button2.Content = new MyControl() { Name = "MyControl2" };
}
}
} public class MyControl : Control
{
public DispatcherTimer timer = new DispatcherTimer();
static MyControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(typeof(MyControl)));
}
public MyControl()
{
timer.Interval = new TimeSpan(0, 0, 2);
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
private void timer_Tick(object sender, EventArgs e)
{
MessageBox.Show(this.Name);
}
}自己把代码简化一下