父窗口关闭时,C#WPF用户控件不处理

时间:2017-01-27 15:31:19

标签: c# wpf user-controls

我有一个主窗口,我们会调用main和一个子窗口,我们会在child我们的child中使用用户控件来呼叫control致电main

程序以child开头,用户会执行一些操作来启动controlFileSystemWatcher其中包含FileSystemWatcher。但是,我开始注意到child事件在Window_Closing关闭后仍在触发。 哦,哦。所以我开始挖......

当我为child订阅UserControl_Unloaded事件时,它会按预期触发。当我订阅control的{​​{1}}事件时,它会按预期触发(在child关闭后立即触发)。所以我在control上放了一个析构函数,在main关闭之前显然没有发生。

那么为什么我的用户控件的析构函数在卸载用户控件时没有处理属性?如果我知道哪些是相关的话,我会包含代码片段......

2 个答案:

答案 0 :(得分:0)

好吧,在输入问题之后,StackOverflow的真棒让我看到this question,它有一个不错的通用答案。

我的解决方案是取消订阅FileSystemWatcher事件中的所有UserControl_Unloaded个事件。简单地将观察者对象设置为null是不够的。对于像.NET这样的托管语言来说,似乎有太多的工作,但我猜不是。

答案 1 :(得分:0)

FileSystemWatcher实施IDisposable。这通常表示类使用垃圾收集器无法自动(或及时)回收的非托管资源(如文件句柄或非托管内存)。 IDisposable提供了Dispose方法,此类可用于正确释放其非托管资源。当然,清理也可以通过其他方法完成,但IDisposable'惯例'使程序员更容易看到哪些类需要清理。这也意味着“处理”这个词。在C#中有一个非常具体的含义。

如果FileSystemWatcher未被处理,它看起来仍然存在。因为您没有删除这些事件处理程序,所以它仍然包含对您的用户控件的引用,因此它仍然存在,并且您继续看到引发的事件。删除事件处理程序是一个好主意(特别是当事件提升对象具有更长的生命周期时),但在这种情况下它只解决症状,而不是根本问题:它允许垃圾收集器回收用户控件,但是FileSystemWatcher还活着。

对于析构函数(它们通常称为C#中的终结函数),很少需要它们。它们可以作为实施IDisposable的类的最后手段 - 以防程序员忘记拨打Dispose - 但是他们的成本很低(终结者需要在队列并且它们由特殊的终结器线程调用)并且您无法控制它们何时被执行。