2016-08-05 10 views
0

私はC#でのマルチスレッドについて学んでいます。それは私を難しくしているので、私はそれをより良く理解するための簡単なプログラムをやっています。forループ内のタスクの開始:予期しない動作

static void Main() 
    { 
     Task[] tasks = new Task[4]; 
     for (int i = 0; i < 4; i++) 
     { 
      tasks[i] = Task.Factory.StartNew(() => { 
       Console.WriteLine(i); 
      }); 
     } 
     Console.ReadKey(); 
    } 

出力が4444である、ない0123は次のように私は期待:

は私が持っている場合ことに気づきました。 なぜですか?

EDIT:

サディクiのループ変数の上に閉じていますので、この行動の理由があることを彼の答えで述べています。しかし、コードThread.sleep(500);をラムダステートメントの外側でループの内側に追加すると、0123が発生します。 なぜ、このコード行を追加するとClousuresによって引き起こされたのでしょうか?

尋ねられた行動の理由は他にもあるようです。あなたは私が書いたものを理解していない場合のためのコード:

static void Main() 
    { 
     Task[] tasks = new Task[4]; 
     for (int i = 0; i < 4; i++) 
     { 
      tasks[i] = Task.Factory.StartNew(() => { 
       Console.WriteLine(i); 
      }); 
      Thread.Sleep(500); 
     } 
     //Now the output is:
     Console.ReadKey(); 
    } 
+0

"なぜ、このコード行を追加すると、clousuresによってこの動作が起こらないのですか?" - ループの各繰り返しの間に500ミリ秒待機しているので、 'Task'がループの次の反復が同じ変数を更新する前に、取り込まれた変数を更新します。 –

答えて

2

ローカル変数を作る - それに値をコピーして、あなたが期待される出力を取得する必要があります

static void Main() 
{ 
    Task[] tasks = new Task[4]; 
    for (int i = 0; i < 4; i++) 
    { 
     int x = i; 
     tasks[x] = Task.Factory.StartNew(() => { 
      Console.WriteLine(x); 
     }); 
    } 
    Console.ReadKey(); 
} 

理由をiが共有されるため、予期せぬ出力が得られます。 You are closing over a loop variable

+0

答え、Sadiqありがとう。しかし、ポイントは私が思った行動ではなく、なぜこの行動ですか? –

+0

@PabloDeLuca - 私の編集をご覧ください。 – Sadique

+0

私の編集もご覧ください。 –

関連する問題