1

この質問は、スタックとスタックフレームに関する多くの誤解の可能性を示していると告白します。うまくいけば、私はここで適切な質問をしています。

C# では、次のようなコードのスタック フレームとローカル変数はどのように処理されますか。これらのケースを興味深いものにしているのは、StartTasks の変数 j と StartTasks2 の変数 i の両方が、これらの変数がスコープ内になくなった後に実行される可能性のあるタスクによって使用され、通常はそれらが実行されるスタック フレームの後に実行されることです。スタック。

また、常に「再作成」されている j のようなローカル変数は、StartTask で発生するように、スコープ外に渡された後に真新しいメモリ スロットを取得する条件と、そのローカル変数が存在する場所 (つまり、StartTasks のスタックフレーム、つまり、フレームを削除することはできません、または他の場所)?

void StartTasks() {
    int i = 0;
    while ( i < 10000 ) {
        int j = i;
        Task.Run( () => ExecuteThis( j ) ); // eac
    }
}

void StartTasks2() {
    int i = 0;
    while ( i < 10000 ) {
        Task.Run( () => ExecuteThis( i ) ); // eac
    }
}


void BigBoss() {
    StartTasks();
    StartTasks2();
    NowMakeMoreCalls();
}
4

2 に答える 2

5

それらは、コンパイラによって生成されたクラスの一部になるように昇格されます。

あなたが提供したものを単純に逆コンパイルすると、いくつかの答えが得られます。

[CompilerGenerated]
private sealed class <>c__DisplayClass5
{
  public int i;
  public Program <>__this;

  public <>__DisplayClass5()
  {
    base.<>ctor();
  }

  public void <CStartTasks2>b__3()
  {
    this.<>4__this.ExecuteThis(this.i);
  }
}

コンパイラはこのクラスを生成し、呼び出し元のクラスへの参照を渡します。また、クローズド オーバー変数をインスタンス フィールドとして格納します。

したがって、質問に答えるために..それらはスタックに割り当てられていません。これらは、コンパイル時に定義され、実行時にインスタンス化されるオブジェクトを形成します。

于 2013-10-24T22:31:50.770 に答える