WPF中是否需在类的Dispose中移除ComboBox的SelectionChanged事件处理器?
问题:WPF ComboBox事件处理器是否需要在Dispose中移除?
我有一个WPF ComboBox,XAML代码如下:
<ComboBox x:Name="MyDropDown" TabIndex="1" SelectedIndex="1"> <ComboBox.Items> <ComboBoxItem>ComboBox Item #1</ComboBoxItem> <ComboBoxItem>ComboBox Item #2</ComboBoxItem> </ComboBox.Items> </ComboBox>
在后台代码中我绑定了事件处理器:
MyDropDown.SelectionChanged += new SelectionChangedEventHandler(MyDropDown_SelectionChanged);
请问我是否需要在类的Dispose方法中移除这个MyDropDown_SelectionChanged事件处理器?
回答
说白了,绝大多数常规场景下不需要,但得结合你的具体情况来看:
首先,你的ComboBox是Window或者UserControl里的静态控件吧?这类UI元素和它们的后台代码类(比如你的Window类)生命周期是绑定在一起的。当Window关闭、被销毁时,WPF的垃圾回收器(GC)会把它们当成一组对象处理——你的后台类持有控件的引用,控件通过事件持有处理器的引用,但因为没有外部的其他代码再引用它们俩,GC会一次性把这些对象都回收掉,不会有内存泄漏的问题。
那什么时候必须手动移除事件绑定?只有当事件处理器所在的类生命周期比控件长的时候:
- 比如你把一个全局单例类的方法绑定到了这个ComboBox的事件上,控件销毁后单例还活着,这时候控件的实例会被单例的事件引用拽着,GC没法回收它,就会出现内存泄漏。
- 又或者你是动态创建/销毁这个ComboBox(比如在一个循环里生成多个临时控件),而你的后台类是长期存在的对象,这时候每次销毁控件后不移除绑定,旧控件的实例会一直被后台类持有,也会导致内存泄漏。
回到你的情况:如果这个ComboBox是Window/UserControl里的固定控件,后台代码就是这个Window/UserControl的代码,那完全没必要在Dispose里移除事件处理器,省心就行。
要是你实在担心内存泄漏的问题,也可以用WPF的WeakEventManager来绑定事件,这是一种弱引用的事件绑定方式,不用手动移除,GC也能正常回收对象,不过对于这种常规的控件绑定来说,有点杀鸡用牛刀的意思。
内容的提问来源于stack exchange,提问作者Harry Boy
相关产品推荐
相关产品推荐

