Reputation: 13
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[] is a BitMap array already filled with bitmap objects. I want to give different members of array for different threads, but sometimes I get IndexOutOfRangeException because m gets too big.It doesn't occur everytime, it's like every other time i run the program. When debugging, every time was smooth and erro never occured. Even with if(m
I'm interested in both the causation of the problem and code changes to avoid this problem.
Upvotes: 1
Views: 227
Reputation: 21956
This piece of code
() => paintSingleThread(parts[m], "Green", height, width)
captures m
variable by reference, not by value. The value of m
after your foreach
loop completes will be threadCount, which is out of range. Your code sometimes work, when the threads are launched fast enough and m still contains the correct value at the time when the new threads are running your lambda. For the same reason it works in debugger.
Simple way to fix:
var part = parts[ m ];
t[ m ] = new Thread( () => paintSingleThread( part, "Green", height, width ) );
This code will capture part
variable into the lambda. Unlike m
, part
is declared within the body of the loop. Each loop iteration will have different instance of part
, and this code should work as you expect.
Upvotes: 3