I need to use 60 threads in one time(parallelly) and for it I use ThreadPool. I have exception here:
temp = 1;
for (int j = 0; j < temp; j++) {
ThreadPool.QueueUserWorkItem(delegate(object notUsed) {
RequestToRajons(rajs_ip[j].ToString(),rajs_name[j].ToString(), sql_str, base_str, saveFileDialog1,j);
});
}
It’s gives me exception that j=1(array out of range). But I have a contidion!
If I use a breakpoint with step, I haven’t got an exception.
This is the classic for/capture issue, because you are “capturing”
j, and there is only onej. All your threads are processing using the samejvariable; the value they see is indeterminate, but the last several threads will most likely see the exit value of the loop, i.e. one too many.Instead:
it sounds silly, but you now have a
jper loop iteration, because the scope of the capture depends on the declaration scope of the variable. Here,jis defined inside the loop. In theforloop, the variable is technically defined outside the loop.Another way to do this is to use the parameter to the thread-pool:
Here’s an expanded version of how “captured variables” and anonymous methods work, the over-simplified version; firstly, the compiler does this for you:
and your method becomes (because
jis technically defined outside the loop):now; can you see that there is only one “capture” object, and that we’re using it at random points in times where
ctx.jis not necessarily what we thought it was? The fix rewrites that as:here, can you see there is a “capture” object per iteration, which is because the
jis declared inside the loop? The “what is a new capture context” depends on the scope of the variables that are captured.