我对C#线程很新,所以请提前为这个新手错误道歉。以下代码的目的是评估存储在名为members的数组中的填充的适合度。过程members.calculateFitness()是一个黑盒子(即我不能修改它以提高性能),所以我试图设置同时调用黑盒子的线程,每个线程将处理1 / THREAD_COUNT个人口成员(因此,如果THREAD_COUNT = 4,则每个线程将处理1/4的人口。)
在第一个for循环中,我初始化每个线程。在第二个for循环中,我启动了线程。
public void ThreadedPrintPopFitness ()
{
int THREAD_COUNT = 1;
int membersPerThread = members.Length / THREAD_COUNT;
Thread[] fitnessCalculator = new Thread[THREAD_COUNT];
int[] threadResult = new int[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; i++) {
int start = i * membersPerThread;
int stop = (i+1) * membersPerThread;
fitnessCalculator [i] = new Thread (() => getMaxFitness (members, start, stop, ref threadResult [i]));
}
for (int i = 0; i < THREAD_COUNT; i++) {
fitnessCalculator [i].Start ();
}
for (int i = 0; i < THREAD_COUNT; i++) {
fitnessCalculator [i].Join ();
}
int maxFitness = 0;
for (int i = 0; i < THREAD_COUNT; i++) {
if (maxFitness < threadResult [i])
maxFitness = threadResult [i];
}
Console.WriteLine ("(ThreadedCount) Fittest Population Member's Fitness: " + maxFitness);
}
private static void getMaxFitness (PopulationMember[] members, int start, int stop, ref int result)
{
int maxFitness = 0;
for (int i = start; i < stop && i < members.Length; i++) {
if (members [i].calculateFitness () > maxFitness) {
maxFitness = members [i].lastFitness;
}
}
result = maxFitness;
}
单步执行代码表明它进入第二个for循环,然后跳回第一个for循环并在整数i上声明一个IndexOutOfBoundsException。我可以看到i = THREAD_COUNT(我尝试过THREAD_COUNT个不同的数字)。
我完全不知所措,我做错了什么? 提前谢谢!
答案 0 :(得分:0)
Servy发现它,我甚至记得现在在John Skeet的书中读到这个。我必须在for循环中复制i,这就解决了。
谢谢!
答案 1 :(得分:0)
如评论中所述,i
被捕获,当增加时,该函数引用新值。
您应该做的是将其值复制到局部变量:
for (int i = 0; i < THREAD_COUNT; i++) {
int start = i * membersPerThread;
int stop = (i+1) * membersPerThread;
int resultId = i;
fitnessCalculator [i] = new Thread (() => getMaxFitness (members, start, stop, ref threadResult [resultId]));
}