Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IndexOutOfRangeException exception when using tasks in for loop in C#

Tags:

c#

loops

task

I am trying to use tasks in a for loop, but I am getting really strange exception! here is my code:

        Task[] tasks = new Task[strarrFileList.Length];
        for (int ii = 0; ii < strarrFileList.Length; ii++)
        {
            tasks[ii] = Task.Factory.StartNew(() => mResizeImage2(ii, strarrFileList[ii], intLongSide, jgpEncoder, myEncoderParameters));
        }
        Task.WaitAll(tasks);

Here is the error:

An exception of type 'System.IndexOutOfRangeException' occurred in mCPanel.exe but was not handled in user code Additional information: Index was outside the bounds of the array.

So basically ii becomes equal to strarrFileList.Length which shouldn't! Does anyone have an explanation/solution for this?

like image 504
NESHOM Avatar asked Aug 07 '14 03:08

NESHOM


People also ask

How do I fix IndexOutOfRangeException?

Solutions to Prevent IndexOutOfRangeException Solution 1: Get the total number of elements in a collection and then check the upper bound of a collection is one less than its number of elements. Solution 2: Use the try catch blocks to catche the IndexOutOfRangeException .

What is IndexOutOfRangeException in C sharp?

An IndexOutOfRangeException exception is thrown when an invalid index is used to access a member of an array or a collection, or to read or write from a particular location in a buffer. This exception inherits from the Exception class but adds no unique members.

What will happen if you try and access an element in an array which does not exist C#?

If we try to access array[3] , it's not there actually, so an index out of bound exception will arise.


1 Answers

try copying ii to a local variable inside the for loop.

Task[] tasks = new Task[strarrFileList.Length];
for (int ii = 0; ii < strarrFileList.Length; ii++)
{
    var currentIndex = ii;
    tasks[currentIndex] = Task.Run(() => mResizeImage2(currentIndex, strarrFileList[currentIndex], intLongSide, jgpEncoder, myEncoderParameters));
}
Task.WaitAll(tasks);

This is needed because you are accessing a modified closure. For example, since Task.Run() will not run right away, and you are simply just passing ii to it (w/out copying it locally), the value of ii may change when the ThreadPool does decide to run that particular Task. More info, see Access to Modified Closure

like image 167
d.moncada Avatar answered Sep 19 '22 07:09

d.moncada