首页 > 解决方案 > 从循环启动多个线程时出现 IndexOutOfRangeException

问题描述

Thread[] t = new Thread[threadCount];
            int m = 0;
            foreach (var thread in t)
            {
                if (m<threadCount)
                {
                    //This one is needed for paintSingleThread as hight of Bitmap
                    int height = parts[m].Height;

                    //this line causes the exception
                    t[m] = new Thread(() => paintSingleThread(parts[m], "Green", height, width));

                    t[m].Start();
                    m++;
                }

            }

parts[] 是一个已经填充了位图对象的位图数组。我想为不同的线程提供不同的数组成员,但有时我会得到 IndexOutOfRangeException,因为 m 太大了。它不会每次都发生,就像我每隔一次运行程序一样。调试时,每次都很顺利,从未出现过错误。即使如果(米

我对问题的原因和避免此问题的代码更改感兴趣。

标签: c#visual-studio

解决方案


这段代码

() => paintSingleThread(parts[m], "Green", height, width)

m通过引用而不是值捕获变量。m循环完成后的值foreach将是 threadCount,超出范围。当线程启动得足够快并且 m 在新线程运行您的 lambda 时仍然包含正确的值时,您的代码有时会起作用。出于同样的原因,它可以在调试器中工作。

简单的修复方法:

var part = parts[ m ];
t[ m ] = new Thread( () => paintSingleThread( part, "Green", height, width ) );

此代码会将变量捕获part到 lambda 中。与m,不同,part在循环体内声明。每次循环迭代都会有不同的 实例part,并且这段代码应该像你期望的那样工作。

这是一个类似的问题。


推荐阅读