C# 动作、闭包和垃圾回收 [英] C# Action, Closure, and Garbage Collection

查看:33
本文介绍了C# 动作、闭包和垃圾回收的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是否需要将 MyAction 设置为 null 以便垃圾收集能够继续处理这些类中的任何一个?

Do I need to set MyAction to null so that garbage collection will be able to proceed with either of these classes?

当两个班级的寿命几乎相同时,我不太担心.当 Class1 的寿命比 Class2 长得多或 Class2 的寿命比 Class1 长得多时,我的问题更合适.

I am less concerned when both classes are to have almost the same lifespan. My question is more appropriate when Class1’s lifespan is much longer then Class2 or when Class2’s lifespan is much longer then Class1.

这里的代码被精简了.假设 Class1 和 Class2 都包含可能影响其生命周期的其他成员和方法.

The code here is stripped down. Assume that both Class1 and Class2 contain other members and methods that may affect their lifespan.

public class Class1 : IDisposable
{
    public Action<string> MyAction { get; set; }

    // Is this necessary?
    public void Dispose()
    {
        MyAction = null;
    }
}

public class Class2
{
    string _result = string.Empty;

    public void DoSomething()
    {
        Class1 myClass1 = new Class1();
        myClass1.MyAction = s => _result = s;
        myClass1.Dispose();
    }
}

推荐答案

我是否需要将 MyAction 设置为 null 以便垃圾收集能够继续处理这些类中的任何一个?

Do I need to set MyAction to null so that garbage collection will be able to proceed with either of these classes?

没有.每当您处置"托管资源时,很有可能您做错了.让垃圾收集器完成它的工作.

No. Any time you "Dispose" of a managed resource, odds are good you are doing it wrong. Let the garbage collector do its work.

当两个班级的寿命几乎相同时,我不太担心.当 Class1 的寿命比 Class2 长得多或 Class2 的寿命比 Class1 长得多时,我的问题更合适.

I am less concerned when both classes are to have almost the same lifespan. My question is more appropriate when Class1’s lifespan is much longer then Class2 or when Class2’s lifespan is much longer then Class1.

这个问题没有任何意义;没有生命周期.存储位置有生命周期.您究竟担心哪些存储位置?你能澄清一下这个问题吗?

The question doesn't make any sense; classes do not have lifetimes. Storage locations have lifetimes. Precisely which storage locations are you worried about? Can you clarify the question?

我注意到对于通过闭包来延长封闭变量的生命周期存在非常严重的担忧;但是,您的问题是如此含糊,以至于很难理解您是否遇到了这种情况.让我演示一下:

I note that there are very serious concerns about extending lifetimes of closed-over variables via closures; your question however is so vague that it is hard to understand whether you are running into such a situation. Let me demonstrate:

class Expensive
{
    public byte[] huge = MakeHugeByteArray();
}

class Cheap
{
    public int tiny;
}

class C
{
    public static Func<Cheap> longLived;
    public static void M()
    { 
        Expensive expensiveLocal = new Expensive();
        Cheap cheapLocal = new Cheap();
        Func<Expensive> shortLived = ()=>expensiveLocal ;
        C.longLived = ()=>cheapLocal;
    }
}

局部变量expensiveLocal的生命周期是多少?局部变量的生命周期通常;通常局部变量的生存时间不超过方法激活.然而,在闭包中可以任意延长局部变量的生命周期,直到闭包的生命周期.在这种特殊情况下,两个 lambdas 共享一个闭包,并且意味着局部变量昂贵的Local 的生命周期至少与局部变量cheapLocal 的生命周期一样长,它具有无限长的生命周期,因为对闭包的引用刚刚存储在一个永久存在的静态字段中.那个大字节数组可能永远被回收,即使似乎唯一引用它的东西很久以前就被收集了;闭包是一个隐藏的引用.

What is the lifetime of local variable expensiveLocal? The lifetime of a local variable is typically short; typically local variables live no longer than the method activation. However, being in a closure extends the lifetime of a local variable arbitrarily long, to the lifetime of the closure. In this particular case, both lambdas share a closure, and that means that the lifetime of local variable expensiveLocal is at least as long as the lifetime of local variable cheapLocal, which has an indefinitely long lifetime because a reference to the closure has just been stored in a static field that lives forever. That big byte array might never be reclaimed, even though the only thing that seems to reference it has been collected long ago; the closure is a hidden reference.

很多语言都有这个问题;C#、VB、JScript 等都有词法闭包,它们没有按生命周期划分为分组变量.我们正在考虑更改 C# 和 VB 以对闭包进行更好的生命周期管理,但目前这是遥遥无期的工作,因此无法保证.

Many languages have this problem; C#, VB, JScript and so on all have lexical closures that are not partitioned to group variables by lifetime. We are considering changing C# and VB to have better lifetime management for closures but that is far-in-the-future work at this point, so no guarantees.

这篇关于C# 动作、闭包和垃圾回收的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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