Reputation: 21
private static int[] Sort(int[] arr)
{
int temp;
int[] result = new int[arr.Length];
Array.Copy(arr, result, arr.Length);
for (int i = 0; i < result.Length - 1; i++)
{
for (int j = i + 1; j < result.Length; j++)
{
if (result[i] > result[j])
{
temp = result[i];
result[i] = result[j];
result[j] = temp;
}
}
}
return result;
}
public static List<List<T>> ChunkBy<T>(this List<T> source, int chunkSize)
{
return source
.Select((x, i) => new { Index = i, Value = x })
.GroupBy(x => x.Index / chunkSize)
.Select(x => x.Select(v => v.Value).ToList())
.ToList();
}
...
List<List<int>> unsortedLists = list.ChunkBy(chunkSize);
int count = unsortedLists.Count;
List<List<int>> lists = new List<List<int>>();
Task<List<int>>[] tasks = new Task<List<int>>[count];
//from 0 to 9
for (int i = 0; i < count; i++)
{
tasks[i] = new Task<List<int>>(() =>
{
lists[i] = Sort(unsortedLists[i].ToArray()).ToList(); //out of range exception i = 10
return lists[i];
});
}
for(int i = 0; i < count; i++)
{
tasks[i].Start();
}
for(int i = 0; i < count; i++)
{
lists[i] = await tasks[i]; //array out of range
}
I'm facing extremely weird error. I have slightly simplified my code and provided the important part.
I'm creating a bunch of tasks, starting them, and then it fails instantly at 3rd loop. For some reason it uses old iterator that ended on 9, and increases it to 10, creating exception. I have no idea what to do, at the moment it looks like error of the environment.
Upvotes: 0
Views: 57
Reputation: 456577
You should never use the task constructor. In this case, use Task.Run
instead.
Your other problem is that the for
loop in C# only defines a single loop variable, and lambdas close over variables, not values. This is why you're seeing an i
that is 10
.
The simplest solution is to do away with the for
loops completely:
var tasks = Enumerable.Range(0, count)
.Select(i => Task.Run(() =>
{
lists[i] = Sort(unsortedLists[i].ToArray()).ToList();
return lists[i];
}))
.ToList();
var results = await Task.WhenAll(tasks);
Upvotes: 1