The exact error:
Index was out of range. Must be non-negative and less than the size of the collection.
I\'ve index arrays and l
You're the victim of accessing modified closure, as it's so succinctly called. Basically, since you're using a task - and a delegate to boot - the value of i
is not guaranteed to be what it is you expect it to be. If you, however, copy i
to a local variable, specific for the scope of one, single iteration, you should be fine.
for (int i = 0; i < addressList.Count; i++)
{
textBox1.Text += ("Task for " + addressList[i] + ":" + portList[i] + " initiated." + Environment.NewLine);
var iCopy = i;
Task.Factory.StartNew(() => PingTaskAdapted(addressList[iCopy], portList[iCopy]));
}
However, as pointed out in this answer by nvoigt, it's far more clear when it comes to readability and maintainability if you copy the values which will be used rather than the iterator value.
Closures capture variables, not values.
Change the code to the following, and you'll see the issue go away:
for (int i = 0; i < addressList.Count; i++) {
textBox1.Text += ("Task for " + addressList[i] + ":" + portList[i] + " initiated." + Environment.NewLine);
var temp = i;
Task.Factory.StartNew(() => PingTaskAdapted(addressList[temp], portList[temp]));
}
Your task will be accessing the list when the task runs. Not sequentially in the line of code you look at in the loop. To make sure that the correct values are captured in the closure (and the lists still exists and has the same values), make local copies outside of the task, that make sure the values are captured at that point in time the loop runs:
var localAddress = addressList[i];
var localPort = portList[i];
Task.Factory.StartNew(() => PingTaskAdapted(localAddress , localPort));