8

この質問をすべて検索しましたが、質問に対する解決策を見つけるのは難しくありませんでした。しかし、私には奇妙な経験があり、理由がわからないので、人々にアドバイスを求めています。ここに私のコードがあります:

    void SetThread()
    {
        for (int i = 0; i < _intArrayLength; i++)
        {
            Console.Write(string.Format("SetThread->i: {0}\r\n", i));
            _th[i] = new Thread(new ThreadStart(() => RunThread(i)));
            _th[i].Start();
        }
    }

    void RunThread(int num)
    {
        Console.Write(string.Format("RunThread->num: {0}\r\n", num));
    }

はい、通常のスレッド コードです。すべてのスレッド配列が RunThread メソッドを 10 回呼び出す必要があると思います。次のようになるはずです

SetThread->i: 0
SetThread->i: 1
SetThread->i: 2
SetThread->i: 3
SetThread->i: 4
SetThread->i: 5
SetThread->i: 6
SetThread->i: 7
SetThread->i: 8
SetThread->i: 9
RunThread->num: 0
RunThread->num: 1
RunThread->num: 2
RunThread->num: 3
RunThread->num: 4
RunThread->num: 5
RunThread->num: 6
RunThread->num: 7
RunThread->num: 8
RunThread->num: 9

これが私が期待するものです。順序は重要ではありません。しかし、私は以下のような結果を得ます。

SetThread->i: 0
SetThread->i: 1
SetThread->i: 2
The thread '<No Name>' (0x18e4) has exited with code 0 (0x0).
The thread '<No Name>' (0x11ac) has exited with code 0 (0x0).
The thread '<No Name>' (0x1190) has exited with code 0 (0x0).
The thread '<No Name>' (0x1708) has exited with code 0 (0x0).
The thread '<No Name>' (0xc94) has exited with code 0 (0x0).
The thread '<No Name>' (0xdac) has exited with code 0 (0x0).
The thread '<No Name>' (0x12d8) has exited with code 0 (0x0).
The thread '<No Name>' (0x1574) has exited with code 0 (0x0).
The thread '<No Name>' (0x1138) has exited with code 0 (0x0).
The thread '<No Name>' (0xef0) has exited with code 0 (0x0).
SetThread->i: 3
RunThread->num: 3
RunThread->num: 3
RunThread->num: 3
SetThread->i: 4
RunThread->num: 4
SetThread->i: 5
SetThread->i: 6
RunThread->num: 6
RunThread->num: 6
SetThread->i: 7
RunThread->num: 7
SetThread->i: 8
RunThread->num: 8
SetThread->i: 9
RunThread->num: 9
RunThread->num: 10

私が期待しているのは、RunThread 関数が引数 (num) を 0 から 9 まで運ぶ必要があるということです。そして、そのエラー メッセージが何であるかわかりません。「スレッド '' ~~ など。誰か、これについて手がかりを教えてくれませんか?

4

2 に答える 2

6

ループ変数に対してクロージャーを作成しています。簡単な修正は、ローカル コピーを作成することです。そのため、スレッドは目的の値を使用します。

void SetThread()
    {
        for (int i = 0; i < _intArrayLength; i++)
        {
           int currentValue = i;
            Console.Write(string.Format("SetThread->i: {0}\r\n", i));
            _th[i] = new Thread(() => RunThread(currentValue));
            _th[i].Start();
        }
    }
于 2013-08-12T00:52:39.037 に答える
3

ParameterizedThreadStartデリゲートを使用するために、次のようにコードを変更することができます。

    for (int i = 0; i < _intArrayLength; i++)
    {
        Console.Write(string.Format("SetThread->i: {0}\r\n", i));
        _th[i] = new Thread((a) => RunThread((int)a));
        _th[i].Start(i);
    }

それ以外の場合、スレッド エントリ ポイント デリゲートから、親メイン スレッドのコンテキストから() => RunThread(i)変数にアクセスしているため、新しいスレッドが開始される前に変更される可能性があります。i

于 2013-08-12T00:48:16.560 に答える