修改
如果有经验的程序员能够验证这种事情,我会证明这种方法可以避免内存泄漏,我会很高兴。我一直在为我的许多编码工作介绍它,但我仍然有一点怀疑。不幸的是,我不够好/不知道调查它的工具。
原始
我最近了解到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参数的定义。
答案 0 :(得分:8)
不幸的是,你提到的博客文章是错误的。 lambda表达式中的内存泄漏没有普遍问题。在博客示例中,永远不会调用终结器,因为作者永远不会从事件中删除匿名方法。因此,.NET运行时认为该方法仍可能稍后调用,无法从内存中删除该类。
在您的代码中,您将在某处释放NewProjectUI实例,这就是所有事件都未被取消以及分配的lambda方法也未被使用的点。然后GC可以删除匿名的lambda-helper-class并释放用过的内存。
所以,再说一遍:在lambda表达式中使用局部变量时,.NET中没有问题。
但是为了使代码更好,将代码从lambda表达式移动到命名方法,并将这些方法添加到事件中。这也可以在不再需要时从事件中删除方法。