c# - 处理一个集合,然后处理它的内容

标签 c# wpf

我有一个对象,其中包含其他对象的集合。我想通过调用基础对象的 dispose 方法来处理它们。集合的 dispose 方法将清除集合,但不会释放其中包含的单个对象。所以我需要我的基础对象循环遍历并处理每个子对象。最后一个细节是,我想确保集合在它包含的单个对象之前被处理掉。

我想我可以通过使用 Dispatcher.BeginInvoke 和低优先级来获得此行为。首先将集合的处置调用传递给它,然后遍历并处置每个单独的项目。 (伪)代码看起来像这样:

class Foo
{
    FooCollection Children;

    void Dispose()
    {
        //unsubscribe from data model events

        CurrentDispatcher.BeginInvoke(Children.Dispose, ApplicationIdle, null);
        foreach (Foo Child in Children)
        {
            CurrentDispatcher.BeginInvoke(Child.Dispose, ApplicationIdle, null);
        }
    }
}
class FooCollection
{
    void Dispose()
    {
        //unsubscribe from data model events

        this.Clear();
    }
}

我走在正确的轨道上吗?还是我只是让自己处于竞争状态?即,在 foreach 完成对子进程的处理调用排队之前,调度程序是否有可能在集合上调用处理?有没有更好的方法来获得所需的行为?

可能值得注意的是,这些类中的每一个都公开事件,并将处理程序 Hook 到其他对象中。我的主要目标是确保在调用 dispose 时优雅地清理所有处理程序。

编辑(8/24): 这些类的实例订阅来自对象的事件,这些事件通常在应用程序的生命周期内持续存在。因此,持久对象维护对这些实例中的每一个的引用。我试图确保每个实例在不再需要实例时取消订阅持久对象的事件。

编辑 2(8/30): 这是 View 模型的一部分,表示从 Web 服务检索的数据层次结构。从 Web 服务检索数据的成本很高,因此返回的实际数据对象通常在应用程序的生命周期内被缓存。数据对象实现 ICollectionChanged 和 IPropertyChanged,相关的 View 模型对象订阅这些事件。应用程序的性质使得用户操作可能会导致 View 模型在 session 期间多次被丢弃和重新创建。数据的性质使得层次结构中通常有数千个节点必须在模型中表示。与此问题相关的主要问题是:

1) 确保丢弃的 View 模型取消订阅底层数据模型的事件

2) 确保以循环遍历废弃 View 模型的完整层次结构的方式完成,不会明显影响用户使用 View 模型的新实例。

我更新了代码示例以更准确地描述情况。所以问题依然存在。这段代码是否会给我预期的结果,即集合及其所有子项将在任何对象实际被处置之前排队等待处置,然后一段时间后线程将在空闲时间时开始处置它们?或者它是否会创建一个竞争条件,在我完成循环之前可能会处理集合?

大多数张贴者都关注收藏品被清除的事实,老实说,清除收藏品可能是不必要的,但这是一种习惯,我认为这是很好的整理工作。

最佳答案

查看此链接,它很好地解释了与事件处理程序相关的垃圾回收:What best practices for cleaning up event handler references?

这实际上取决于您的事件安排。如果您有从其他更持久的对象接收事件的对象,它们将坚持接收这些事件,直到事件源被 GC 处理。这表明如果你真的需要回收这个内存(这些对象有多大?你运行它的系统是什么?)你的 dispose 方法可能应该清除你连接到的事件(使用 -= 运算符)你处理完对象后,您必须自己调用此 Dispose 方法...

不需要清除集合 - 只需确保对您已完成的任何对象的所有引用都设置为 null。当不存在引用且无需维护事件处理程序时,GC 将收集该对象。

我也不会担心调度员..取消订阅事件不应该造成性能问题。

您不需要选择何时处置托管对象 - GC 可以。你不能在你处理它的 child 之前处理一个集合......因为你根本不能处理一个集合!您只能准备一个用于垃圾回收的托管对象,方法是

(1) 清除事件处理器和

(2) 摆脱所有对您已完成的对象的引用。

GC 会处理剩下的事情。

关于c# - 处理一个集合,然后处理它的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7181047/

相关文章:

.net - 是否有 WPF XAML 用于统一拟合但恒定的 StrokeThickness

c# - 如何在 WPF 中不使用打印对话框直接打印?

c# - 无窗口 WPF 应用程序

wpf - 使用 WPF WebBrowser 将字典传递给 ObjectForScripting

c# - 使用 C# .NET Core 3 使用 SSL 证书连接到 MySQL 数据库

c# - 让应用程序等待变量更新

c# - 修改全局系统菜单

c# - 在 WPF 中取消取消选中

c# - 客户端发现响应内容类型为 "but expected ' text/xml' 请求失败,响应为空

c# - 异步任务<TResult> - 返回值