c# - Action/Lambda 表达式内存管理问题

标签 c# memory-management .net-4.0

我将一个 Action 存储在局部变量中,然后在该局部变量超出范围后使用。在我使用它之前是否有被清理的危险?这是一个例子:

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 知道不要清理它吗?

最佳答案

我建议您参阅 C# 4 规范的第 5.1.7 节,其中说:

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.

即使控制通过了本地范围的末尾,本地的生命周期也会延长。在实践中,我们通过将局部变量转换为闭包类的字段,然后通过在委托(delegate)(或表达式树)中引用它来保持类的事件来实现这一点。

请注意,您可能会遇到相反的问题;有时事物的生命周期比您希望的要长:

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

今天在 C# 中的工作方式是为两个委托(delegate)生成的闭包使“廉价”和“昂贵”的事件与长生命周期委托(delegate)的生命周期保持一致,即使长生命周期委托(delegate)实际上并不存在用“贵”! (VB、JScript 等很多有闭包的语言也有这个问题。)

我们在这里可以做的是在编译器中检测这种情况并创建两个闭包。我们正在考虑为 C# 的 future 版本这样做。

关于c# - Action/Lambda 表达式内存管理问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6202988/

相关文章:

c# - 将 ASP MVC5 站点部署到 Azure,收到 500 内部服务器错误

java - 如何找出设备中存在的广告垃圾?

c# - 在 CollectionViewSource 的筛选期间保留 SelectedItem

c# - LINQPad:使用 (.NET4) VS2010 程序集时出现 "BadImageFormatException"?

c# - 流写入滞后于我的 GUI

c# - ASP.Net MVC 4 WebAPI 自定义路由

c# - 类型加载异常 : Could not load type IHttpResponseStreamWriterFactory from assembly

c++ - 用户提供的多余数据会怎样?

java - 不需要在 android 中执行 opengl 删除功能?

c# - 在运行时更改表达式委托(delegate)主体?