C#Threading ...不明白为什么我的循环为5;

Luk*_* Xu 2 c#

class Thread1_8
{
    static int shared_total;
    static int thread_count;
    static readonly object locker = new object();

    static void Main()
    {
        int[,] arr = new int[5, 5] { { 1,2,3,4,5}, {5,6,7,8,9}, {9,10,11,12,13}, {13,14,15,16,17}, { 17,18,19,20,21} };

        for(int i = 0; i < 5; i++)
        {
            new Thread(() => CalcArray(i, arr)).Start();
        }


        while(thread_count < 5)
        {

        }
        Console.WriteLine(shared_total);
    }

    static void CalcArray(int row, int[,] arr)
    {

        int length = arr.GetLength(0);
        int total = 0;
        for(int j = 0; j < length; j++)
        {
           total += arr[row,j];
        }

        lock (locker)
        {
            shared_total += total;
            thread_count++;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我一直收到System.IndexOutOfRangeException.

原因是因为出于某种原因,我在初始for循环中的"i"被设置为5并且STILL由于某种原因进入循环.我不明白为什么.起初我以为可能是因为我创建的每个线程都在递增数组,但它不应该因为一个Thread有一个完整的独立执行路径,它应该直接跳转到CalcArray方法.

das*_*ght 6

这种情况发生的原因很微妙:当你这样做时

for(int i = 0; i < 5; i++) {
    new Thread(() => CalcArray(i, arr)).Start();
}
Run Code Online (Sandbox Code Playgroud)

变量i经历值0一直到5,此时循环停止,因为5 < 5求值为false.

循环结束线程开始,因此row它看到的值5不是0到4.

这可以通过row在循环内部创建局部变量来解决.

您的代码中的另一个问题是在繁忙的循环中检查thread_count内部Main而没有锁定.这不是与线程同步的最佳过程.考虑ManualResetEventSlim改用.