Почему вы даже пытаетесь использовать ThreadLocal
хранилище здесь вместо локальной переменной внутри Задачи?Библиотека Task Parallel может повторно использовать поток для выполнения более чем одной задачи, и локальное хранилище вашего потока будет перезаписано.В первом примере это может работать, так как вы не сбрасываете его каждый раз, когда поток используется повторно, но это будет лучше:
for (int i = 0; i < tasks.Length; i++)
{
tasks[i] = new Task<int>(() =>
{
int sum = 0;
for (int j = 1; j <= 3; j++)
{
sum += j;
}
return sum;
});
}
Объяснение того, что на самом деле делает ваш код:
В первом примере вы инициализируете локальное значение отдельного потока равным 0 в потоке запуска, но делаете это несколько раз (явно не то, что вы намеревались, поместив инициализацию в цикл for - ошибка №1).Вы накапливаете в локальной переменной задачи, которая хороша, но затем вы перезаписываете локальное значение потока результатом, даже если это локальное значение потока может быть разделено между несколькими задачами, выполняющимися последовательно (например, один поток на ядро) - ошибка № 2.Это приведет к тому, что некоторые задачи будут использовать одно и то же локальное значение потока.Ошибка № 3: когда вы возвращаете локальное значение потока, вам повезло, потому что оно будет таким же, как temp, и никакой другой поток не мог его изменить, что эквивалентно использованию локальной переменной в задаче.
ВВаш второй пример вы делаете ту же ошибку при инициализации.Но затем вы переходите к двойному количеству значений, потому что локальное значение потока не сбрасывается в начале каждой задачи, поэтому, если две задачи выполняются в одном потоке, первая может вернуть 1 + 2 + 3, а вторая может вернуть 6 + 1 +.2 + 3