我正在尝试创建自己的自定义ToolTip类,在构造函数中注册Loading事件。如何取消订阅此活动?当我在终结器/析构函数中执行此操作时,它会导致异常,尤其是当我打开应用程序的新窗口并关闭它时:
COM对象已与其基础RCW分离,无法使用。
这是我的代码:
public class CustomToolTip: ToolTip
{
public CustomToolTip()
{
this.Loading += CustomToolTip_Loading;
}
protected void CustomToolTip_Loading(Windows.UI.Xaml.FrameworkElement sender, object args)
{
// my logic here
}
~CustomToolTip()
{
this.Loading -= CustomToolTip_Loading;
}
}
当我创建自定义Flyout控件并尝试取消订阅终结器中的Opening事件时,也会发生此异常。
我的代码:
public class CustomFlyout: Flyout
{
public CustomFlyout()
{
this.Opening += CustomFlyout_Opening;
}
private void CustomFlyout_Opening(object sender, object e)
{
// my logic here
}
~CustomFlyout()
{
this.Opening -= CustomFlyout_Opening;
}
}
任何帮助都将不胜感激。
除非直接处理非托管资源,否则不应该在类中定义终结器。
如果您只想处理一次事件,而不管您的控件加载了多少次,那么当Loading
事件被引发时,您可以简单地注销事件处理程序:
public class CustomToolTip : ToolTip
{
public CustomToolTip()
{
this.Loading += CustomToolTip_Loading;
}
protected void CustomToolTip_Loading(Windows.UI.Xaml.FrameworkElement sender, object args)
{
this.Loading -= CustomToolTip_Loading;
//...
}
}
否则,会出现Unloading
事件:
private void CustomToolTip_Unloaded(object sender, RoutedEventArgs e)
{
this.Loading -= CustomToolTip_Loading;
this.Unloaded -= CustomToolTip_Unloaded;
}
还要注意,只有当发布服务器的寿命比订阅服务器的寿命长时,从事件中注销以避免内存泄漏才是重要的。
正如T.Schwarz所说,如果仍然有对对象的引用,它将永远无法执行终结器。因此,您需要在其他地方删除eventHandlers,例如Dispose方法。
public class CustomToolTip : ToolTip,IDisposable
{
……
public void Dispose()
{
this.Loading -= CustomToolTip_Loading;
}
}