我已经从局部变量的匿名事件处理退订?退订、变量、局部、我已经

2023-09-03 15:52:48 作者:[青丝青衫亦青城]

如果我有一个code,它看起来是这样的:

If I have a code that looks something like this:

public void Foo()
{
    Bar bar = new Bar();

    bar.SomeEvent += (sender, e) =>
    {
        //Do something here
    };

    bar.DoSomeOtherThingAndRaiseSomeEvent();
}

威尔时,方法用尽的范围,否则我将不得不从事件到prevent手动取消,因为一个内存泄漏收集参照 SomeEvent

Will bar be collected when the method runs out of the scope, or will I have to manually unsubscribe from the event to prevent a memory leak because of a reference to SomeEvent?

推荐答案

您的情况是好的;事件的用户的不会prevent中的发布者的被收集,但相反可能发生。

Your situation is fine; the event subscriber will not prevent the publisher from being collected, but the opposite can happen.

例如,

class Foo
{
    public event EventHandler FooEvent;

    void LeakMemory()
    {
        Bar bar = new Bar();

        bar.AttachEvent(this);
    }
}

class Bar
{
    void AttachEvent(Foo foo)
    {
        foo.FooEvent += (sender, e) => { };
    }
}

在这种情况下,酒吧 LeakMemory 创建的实例不能被收集,直到

In this case, the instance of Bar created within LeakMemory can't be collected until either

将拉姆达psented匿名方法重新$ P $从 FooEvent 删除的调用列表 foo的实例,它连着可以收集到 The anonymous method represented by the lambda is removed from FooEvent's invocation list The instance of Foo to which it's attached can be collected

这是因为该事件(这只是一些语法糖在一个普通的代理)实例持有到委托列表它被调用时调用,并且每种代表有,反过来,一个引用,它的附加到该对象(在这种情况下,该实例酒吧)。

This is because the event (which is just some syntactic sugar over an ordinary delegate instance) holds onto a list of delegates to invoke when it's invoked, and each of these delegates has, in turn, a reference to the object that it's attached to (in this case, the instance of Bar).

请注意,我们只谈论收集的资格的位置。只是因为它的资格并没有说任何事情的在的(甚至,真的,的如果的),它会被收集起来,只是它的可以的是

Note that we're only talking about collection eligibility here. Just because it's eligible doesn't say anything about when (or even, really, if) it will be collected, just that it can be.