动作/λ防爆pression内存管理问题 [英] Action/Lambda Expression Memory Management Question

查看:123
本文介绍了动作/λ防爆pression内存管理问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我存储在一个局部变量的作用,那么我使用后局部变量超出范围。它是在被清理之前,我使用它的危险?下面是一个例子:

I'm storing an action in a local variable, then I'm using after that local variable is out of scope. Is it in danger of being cleaned up before I use it? Here is an example:

public List<object> GetMaps() {
    Action<Customer1, Customer2> baseMap = (Customer1 c1, Customer2 c2) => {
        c2.FirstName = c1.FirstName;
    };

    var list = new List<object>() {
        new Action<SpecialCustomer1 c1, SpecialCustomer2 c2>() {
            baseMap(c1, c2);
            c2.SpecialProperty = c1.SpecialProperty;
        },
        new Action<SpecialCustomer1 c1, SpecialCustomer2 c2>() {
            baseMap(c1, c2);
            c2.SpecialProperty2 = c1.SpecialProperty2;
        },
    };

    return list;
}

所以,你可以在这个例子中看到,该函数返回的调用为baseMap 操作的列表。 为baseMap 只是一个局部变量。是事实,这就是所谓的其他行动中足够的对于.NET,不知道把它清理干净?

So, you can see in this example that the function is returning a list of actions that call baseMap. baseMap is just a local variable. Is the fact that it's called within the other actions enough for .NET to know not to clean it up?

推荐答案

我是指你的C#4的规格,它说的第5.1.7节:

I refer you to section 5.1.7 of the C# 4 spec, which says:

如果局部变量是由匿名函数捕获,其寿命​​至少延伸到从匿名函数创建委托或离pression树,连同来引用该捕获的变量的任何其他目的,有资格垃圾收集。

If the local variable is captured by an anonymous function, its lifetime extends at least until the delegate or expression tree created from the anonymous function, along with any other objects that come to reference the captured variable, are eligible for garbage collection.

即使控制转到本地的范围的端部,在本地的寿命得以延长。在实践中,我们做到这一点通过将当地变成一个封闭类的字段,然后保持类活在委托引用它(或前pression树)。

Even if control passes the end of the scope of the local, the lifetime of the local is extended. In practice we do this by turning the local into a field of a closure class, and then keeping the class alive by referencing it in the delegate (or expression tree).

请注意,虽然你可以运行到相反的问题;有时事情活得比你希望他们:

Note though that you can run into the opposite problem; sometimes things live longer than you want them to:

Expensive expensive = new Expensive();
Cheap cheap = new Cheap();
Action longlived = ()=>M(cheap);
Action shortlived = ()=>M(expensive);

今天这个工作在C#的方式是两个代表产生的闭合不断既便宜和贵活着,只要长寿命委托的寿命,即使长寿命委托不实际用贵! (VB,JScript和有倒闭很多其他语言也有这个问题。)

The way this works in C# today is the closure generated for the two delegates keeps both "cheap" and "expensive" alive as long as the lifetime of the longer-lived delegate, even though the longer-lived delegate does not actually use "expensive"! (VB, JScript and many other languages that have closures also have this problem.)

我们所能做的就是在这里检测到这种情况,编译器和创建两个闭包。我们正在考虑这样做对C#的未来版本。

What we could do here is detect this situation in the compiler and create two closures. We're considering doing that for a future version of C#.

这篇关于动作/λ防爆pression内存管理问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆