1
3
如果“后一个对象”是使用事件的对象,“前一个”对象是订阅事件的对象,“前一个”对象必须有某种方式将事件信息传递给“后一个”对象,这意味着它将有一些对“后一个”的引用。很可能,这将使“后一个”对象 曾经 作为GC候选人。 也就是说,我建议避免通过终结器进行这种类型的托管资源分配,除非绝对必要。你描述的建筑看起来很脆弱,很难纠正。这可能是IDisposable的更好的候选者,因为终结器是“最后一道沟”清理工作。 虽然 IDisposable 通常是关于释放本机资源-它可以是关于释放任何资源,包括订阅信息。 另外,我会尽量避免有一个对象引用的全局集合-让您的对象在内部只使用 WeakReference . 一旦“后一个”对象被收集,“前一个”对象的weakreference将不再有效。下次引发事件订阅时,如果内部weakreference不再有效,您可以自己取消订阅。不需要全局队列、列表等-它应该只起作用… |
2
0
我将把对象称为“发布者”和“订户”,并重申我对问题的理解: 在C中,发布服务器将(有效地)保存对订阅服务器的引用,防止订阅服务器被垃圾收集。我该怎么做才能在不显式管理订阅的情况下对订阅服务器对象进行垃圾收集? 首先,我建议你做 我能做的一切 首先要避免这种情况。现在,我要继续假设你有,考虑到你无论如何都要发布这个问题=) 接下来,我建议挂接发布者事件的添加和删除访问器,并使用weakreferences集合。然后,只要调用事件,就可以自动取消这些订阅的挂起。这里有一个 非常粗糙,未经测试 例子:
|
3
0
让我确保我理解——您担心来自仍然订阅收集到的事件发布者的事件订阅服务器的泄漏吗? 如果是这样的话,我想你不必担心。 我的意思是假设“前”对象是事件订阅服务器,“后”对象是事件发布服务器(引发事件): 订阅服务器(前者)被“订阅”的唯一原因是您创建了一个委托对象并将该委托传递给发布服务器(“后者”)。 如果查看委托成员,它将引用订阅服务器对象和将要执行的订阅服务器上的方法。所以有一个引用链看起来像这样:publisher-->delegate-->subscriber(publisher引用delegate,后者引用subscriber)。这是一个单向链——订阅方不包含对委托的引用。 因此,保持代理的唯一根目录是发布服务器(“后者”)。当后者符合GC的条件时,代理也符合。除非您希望订户在取消订阅时采取某些特殊措施,否则当收集到代理时,他们将有效地变为取消订阅--没有泄漏)。 编辑 根据supercat的评论,问题似乎在于发布服务器使订阅服务器保持活动状态。 如果这是问题所在,那么终结器将不会帮助您。原因:您的发布服务器对您的订阅服务器(通过代理)有一个真正的、实质性的引用,并且发布服务器是根目录(否则它将符合GC的条件),因此您的订阅服务器是根目录,并且不符合定稿或GC的条件。 如果您在使订阅服务器保持活动状态方面遇到问题,我建议您搜索弱引用事件。以下是一些链接,可以帮助您开始: http://www.codeproject.com/KB/cs/WeakEvents.aspx http://www.codeproject.com/KB/architecture/observable_property_patte.aspx . 我也得处理一次。大多数有效的模式都涉及到更改发布者,使其对委托具有弱引用。然后你就有了一个新的问题——委托并没有根深蒂固,你必须以某种方式保持它的活力。上面的文章可能是这样的。有些技术使用反射。 我曾经用过一种不依赖思考的技巧。但是,它要求您能够在发布服务器和订阅服务器中对代码进行更改。如果你想看看那个溶液的样品,请告诉我。 |
4
0
让我们再试一次。是否可以将事件处理程序添加到发布服务器,如下所示:
这样,您的委托就不会直接引用订阅者,并且在订阅者被收集时自动将其自身取消挂钩。您可以将它实现为订阅服务器类的私有静态成员(为了封装的目的),只要确保它是静态的,以防止无意中持有对“this”对象的直接引用。 |
Emopusta · 从后端到前端的图像路径不工作 2 年前 |
Asdrubal Hernandez · Linq查询特定数组索引出错 2 年前 |
Niyazi Babayev · 如何在表达式中动态应用表达式? 2 年前 |
Dansih · .Net核心自定义身份验证方案 2 年前 |
lolorekkk · 面板插入。NET WinForm 2 年前 |