在完成执行后,内联代码是否将[在其中写入的方法]保留在内存中?

Hom*_*mam 2 .net c# callback

根据我所知,当我在C#中定义一个方法时,在完成执行此方法的块[当GC想要]时,此方法中的局部变量将从内存中释放,

但是如果我在方法中有内联回调,那么这些局部变量是否也会从内存中释放出来?

在下面的例子中,[x]变量将在完成执行方法后保持其值,并且消息将显示[x]的值而没有问题,尽管它在回调中!

    private void MyMethod()
    {
        int x = 1;
        System.Timers.Timer t = new System.Timers.Timer(1000);
        t.Elapsed += (sender, e) => MessageBox.Show((x++).ToString()); ;
        t.Start();
    }
Run Code Online (Sandbox Code Playgroud)

Tom*_*cek 5

该变量x在与lambda函数关联的闭包中捕获.这意味着值x实际上并不存储在与堆的执行相关联的堆栈MyMethod上(在从lambda函数引用的对象中).

以下示例(粗略地)显示了C#编译器如何转换代码:

class $$MyMethod$$Closure { 
  public int x;
  void Function(object sender, EventArgs e) {
    MessageBox.Show((x++).ToString());
  }
}

private void MyMethod() {
    var $$closure = new $$MyMethod$$Closure();
    $$closure.x = 1; 
    System.Timers.Timer t = new System.Timers.Timer(1000); 
    t.Elapsed += $$closure.LambdaFunction; 
    t.Start(); 
}
Run Code Online (Sandbox Code Playgroud)

如您所见,x变量现在存储在堆分配的对象(称为闭包)中.只要定时器可以调用该方法(并且只要x可以访问),该对象将是活动的,但是一旦移除了定时器,闭包也将被垃圾收集.

值得注意的是,编译器只捕获 lambda函数中实际使用的那些局部变量(因此,如果方法中有一些大数据,它们不会意外地保持活动时间超过需要).