0

私はこのコードを持っています。これは私が望んでいたように動作しますが、その理由が正確にはわかりません。C、C++ のスタックについて考えると、呼び出しごとに p 変数がスタックに置かれ、メソッドが戻ると消去されると思います。スレッドの閉鎖はどのようにそれをキャプチャし、さらに毎回正しい値をキャプチャしますか? 出力は私が望んでいたものです-ファイルは「_a」、「_b」、「_c」です。

public enum enumTest
    {
        a = 1,
        b =2,
        c=3
    }     
 private void Form1_Load(object sender, EventArgs e)
    {

        callme(enumTest.a);
        callme(enumTest.b);
        callme(enumTest.c);
    }

    private void callme(enumTest p)
    {
        Thread t = new Thread(() =>
            {
                Thread.Sleep(2000);
                Guid guid = Guid.NewGuid();
                File.WriteAllText(guid.ToString() + "_" + p.ToString(), "");
            });
        t.Start();
    }
4

3 に答える 3

1

それはクロージャーについてではありません。ここでは、値をキャプチャするものはありません。

ここで起こっていることは、pパラメーターが値によってスレッドの関数にコピーされることです。関数に渡すたびに、 の新しい値p 関数にコピーされます。

于 2013-01-31T09:12:36.040 に答える
1

ラムダは単に美化された匿名のデリゲートです

enumTest pRick の記事では、コンパイラが値 andを処理するクラスを生成する方法について説明していますdelegate

また、 Where does anonymous function body variables saved の良い情報も参照してください。

基本的に、コンパイラは、ラムダに渡す必要があるローカル変数を使用して、「クロージャ クラス」の新しいインスタンスを作成します。これが、出力が正しい理由です。

アップデート

の場合:

for (int i=0; i<10; i++) 
{
    var t = new Thread(() => { Console.WriteLine(i); }); 
    t.Start(); 
}

変数iは と の間で共有されforますlambda。各スレッドは同じにアクセスしていiます。また、for ループはスレッドが実行される前に終了する傾向があるため、表示されるのは「10」だけです。

http://msdn.microsoft.com/en-us/library/0yw3tz5k(v=vs.80).aspxを参照してください。

于 2013-01-31T09:26:11.413 に答える
1

スレッドの閉鎖はどのようにそれをキャプチャし、さらに毎回正しい値をキャプチャしますか?

それがコンパイラマジックです。pパラメータがラムダによって使用されている という理由だけで、コンパイラはそれを別の方法で扱います。pスタックではなくヒープに置かれます。が終了した後も存在するのはそのためcallme()です。

于 2013-01-31T09:27:42.787 に答える