Lambda和内存泄漏:寻找替代方法

时间:2012-10-20 15:12:36

标签: c# events lambda

修改

如果有经验的程序员能够验证这种事情,我会证明这种方法可以避免内存泄漏,我会很高兴。我一直在为我的许多编码工作介绍它,但我仍然有一点怀疑。不幸的是,我不够好/不知道调查它的工具。

原始

我最近了解到lambda表达式的一些用法会造成内存泄漏:

    ProjectData Project;

    void OnLaunchNewProject()
    {
        NewProjectUI newProjectUI = new NewProjectUI();
        newProjectUI.OnCompleted += (o, e) =>
            {
                Project = newProjectUI.NewProject;
                view.Content = string.Format("Project {0} was created and saved successfully.", Project.Name);
            };
        newProjectUI.OnCancelled += (o, e) => { view.Content = "Operation was cancelled.";};
        view.Content = newProjectUI;
    }

我在这个blog中了解了这种方法的不良影响。

我不完全理解在lambda表达式中引用局部变量的影响,这限制了我绕过问题的能力。

typical approach和lambda的使用之间,理想的妥协是什么?我喜欢lambda的东西是在我不需要的时候跳过我的类体(发送者/路由的args)中的EventHandler参数的定义。

1 个答案:

答案 0 :(得分:8)

不幸的是,你提到的博客文章是错误的。 lambda表达式中的内存泄漏没有普遍问题。在博客示例中,永远不会调用终结器,因为作者永远不会从事件中删除匿名方法。因此,.NET运行时认为该方法仍可能稍后调用,无法从内存中删除该类。

在您的代码中,您将在某处释放NewProjectUI实例,这就是所有事件都未被取消以及分配的lambda方法也未被使用的点。然后GC可以删除匿名的lambda-helper-class并释放用过的内存。

所以,再说一遍:在lambda表达式中使用局部变量时,.NET中没有问题。

但是为了使代码更好,将代码从lambda表达式移动到命名方法,并将这些方法添加到事件中。这也可以在不再需要时从事件中删除方法。