简体   繁体   English

lambda表达式的生命范围是什么?

[英]What is life scope of lambda expression?

What is the lifetime of a lambda expression? lambda表达式的生命周期是多少?

Here is my problem: I have a button1.Click event subscribed by a lambda expression. 这是我的问题:我有一个由lambda表达式订阅的button1.Click事件。 I don't know if I need need to unsubscribe it (which is not easy because it is anonymous)? 我不知道是否需要取消订阅(这是不容易的,因为它是匿名的)? Or I don't have to, because it is in the same lifetime of the control(button1) it is attached? 或者我不必,因为它与控件(button1)的生命周期相同?

button1.Click += (s, e) => { /*Do something; */};

Since the lambda expression is associated with the button,it will live as long as the button is not destroyed from memory.for your question 由于lambda表达式与按钮相关联,因此只要按钮没有从内存中销毁,它就会存在。对于你的问题

I don't know if I need need to unsubscribe it (which is not easy because it is anonymous)? 我不知道是否需要取消订阅(这是不容易的,因为它是匿名的)?

Lambda expressions can be saved to a EventHandler delegate,which gives you the option to access the lambda and unsubscribe from the event.Here is the code. Lambda表达式可以保存到EventHandler委托,它为您提供访问lambda和取消订阅事件的选项。这是代码。

    EventHandler myEvent= (s, e) => { /*Do something; */};  
    //Subscribe
    button1.Click += myEvent;
    //Unsubscribe
    button1.Click -= myEvent;

probably the best explanation on this topic here Should I unsubscribe from events? 可能是关于这个主题的最好解释我应该取消订阅活动吗?

As all normal CLR objects resulting delegate's lifetime will be defined by whatever have references to it. 因为所有正常的CLR对象导致委托的生命周期将由引用它的任何内容定义。 In your case only button1 holds the reference via Click . 在您的情况下,只有button1通过Click保存引用。 As result it will be propely available for garbage collection at the same time as button1 . 因此,它将与button1同时可用于垃圾收集。 Unless there are special reasons (ie want to change handler to another one) you don't need to do anything special to "free" it. 除非有特殊原因(即想要将处理程序更改为另一个),否则不需要做任何特殊的“释放”它。

You can easily retain a reference to a reference to your event handler by capturing it with a local variable. 您可以通过使用局部变量捕获对事件处理程序的引用来轻松保留对其的引用。

        EventHandler click = (s, e) => { /* Do something; */ };

Then you can attach it like so: 然后你可以像这样附上它:

        this.button1.Click += click;

Cleaning up can be a little more tricky because it often requires you to make a class-level variable to hold the reference to the handler. 清理可能会有点棘手,因为它通常需要您创建一个类级变量来保存对处理程序的引用。 This leads to code scattered throughout your class. 这导致代码分散在整个班级中。

However, there's a fairly easy way to handle it. 但是,有一种相当简单的方法来处理它。 Make a class-level cleanup action to capture all of you clean-up actions like so: 进行类级别cleanup操作以捕获所有cleanup操作,如下所示:

        private Action cleanup = () => { };

Now your code to attach an event handler can be located nicely in a single method like so: 现在,附加事件处理程序的代码可以很好地定位在单个方法中,如下所示:

        EventHandler click = (s, e) => { /* Do something; */ };
        this.button1.Click += click;
        cleanup += () => this.button1.Click -= click;

When you are done with your form you can just do the clean-up very quickly like this: 当您完成表单后,您可以非常快速地进行清理:

        cleanup();

The cool thing is that you can add all sorts of clean-up code to this action variable. 很酷的是,您可以为此操作变量添加各种清理代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM