【问题标题】:C# does removing an object from a List clear event handlersC# 确实从 List 清除事件处理程序中删除对象
【发布时间】:2019-10-28 09:55:20
【问题描述】:

我有一个带有 SignalR 的 .NET Core 后端,它接受客户端连接。 在每个连接上,都会创建一个所谓的“调度程序”并将其存储在字典中。关闭连接后,此调度程序对象将从列表中删除。

现在,对于这些调度程序对象,我为对象属性设置了一些 CollectionChanged 处理程序,如下所示:

...
scheduler.Grades.CollectionChanged += (s, e) => this.GradesListener(s, e, connectionId);
scheduler.Raws.CollectionChanged += (s, e) => this.MaterialsListener(s, e, connectionId);
scheduler.Heats.CollectionChanged += (s, e) => this.HeatsListener(s, e, connectionId);
...

因为应用程序中存在内存泄漏,我的问题是:如果我从字典中删除调度程序(我使用 Dictionary.Remove(key) 执行此操作),是否也删除了事件侦听器?我会这么认为,因为属性(Grades, Raws, Heats...)也会被删除,对吧?

如果处理程序没有自动删除,我将如何“取消注册”它们?

如果我需要提供更多代码,请告诉我。

很抱歉,如果以前有人问过这样的问题,我只是找不到答案。

【问题讨论】:

  • 为防止资源泄漏,在订阅事件并完成他的工作后,您应该使用“-=”取消订阅,如下所示:scheduler.Grades.CollectionChanged -= (s, e) => this。 GradesListener(s, e, connectionId)
  • @MohammedNoureldin 你说的是 SignalR 连接吗?我从 OnDisconnectedAsync 方法中的 Dictionary 中删除了调度程序,然后调用了 await base.OnDisconnectedAsync(e);。这还不足以停止 signalR 连接吗?
  • 你怎么知道有内存泄漏?你怎么知道它是事件处理程序?除非您分析了应用程序的内存——它会准确地告诉你分配了什么——否则你就是在黑暗中拍摄。
  • @IanKemp 我知道,因为将调度程序添加到列表中并创建事件处理程序是我在建立连接时唯一要做的事情。我查看了内存图,每个连接都会在堆上永久添加几 MB。

标签: c# memory .net-core signalr


【解决方案1】:

你说得对, 从 Grades、Raws 和 Heats 中删除条目后, GC 会很好地清理内存。

问题是直到你删除它们 this 实例无法被清理。

您可以找到更多信息如何避免内存泄漏here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-22
    • 1970-01-01
    • 2013-11-02
    • 1970-01-01
    • 2010-11-21
    • 2010-11-14
    • 2015-05-22
    • 2017-11-03
    相关资源
    最近更新 更多