閉鎖はここであなたの問題です。
基本的に、(ループ内で) ラムダを作成するときに値を取得するのではなく、必要なときに値を取得します。そして、コンピューターは非常に高速であるため、それが起こる頃には、すでにループから外れています。値は 3 です。以下に例を示します (まだ実行しないでください)。
private void buttonDoSomething_Click(object sender, EventArgs e)
{
List<Thread> t = new List<Thread>();
for (int i = 0; i < 3; i++)
{
t.Add(new Thread (() => Console.Write(i)));
t[i].Start();
}
}
結果がどうなるかを考えてみてください。考えているのでは012
ないでしょうか?
今すぐ実行してください。
結果は になります333
。
これを修正する変更されたコードを次に示します。
private void buttonDoSomething_Click(object sender, EventArgs e)
{
List<Thread> t = new List<Thread>();
string[] bla = textBoxBla.Lines;
for (int i = 0; i < bla.Length; i++)
{
int y = i;
//note the line above, that's where I make the int that the lambda has to grab
t.Add(new Thread (() => some_thread_funmction(bla[y])));
//note that I don't use i there, I use y.
t[i].Start();
}
}
これでうまくいきます。今回は、ループが終了すると値が範囲外になるため、ラムダはループが終了する前に取得するしかありません。これにより、期待される結果が得られ、例外はありません。