4

编辑:

如果一位有能力验证此类事情的有经验的程序员向我展示了这种方法可以避免内存泄漏的证据,我将非常感激。我一直在将它引入我的许多编码工作,但我仍然有一个小小的疑问。不幸的是,我不够好/不知道调查它的工具。

原来的:

我最近了解到 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;
    }

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

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

典型方法和使用 lambda 之间,理想的折衷方案是什么?我喜欢 lambda 的一点是当我不需要 EventHandler 的参数时在我的类的主体(发送者/路由参数)中跳过它们的定义。

4

1 回答 1

8

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

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

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

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

于 2012-10-20T15:29:09.307 回答