У меня есть некоторые проблемы, включающие Параллель для циклов и добавляющие к Списку. Проблема, тот же код может генерировать другой вывод в разное время. Я настроил некоторый тестовый код ниже. В этом коде я создаю Список 10 000 международных значений. 1/10-й из значений будет 0, 1/10-й из значений будет 1, полностью до 1/10-го из значений, являющихся 9.
После установки этого Списка я устанавливаю Параллель для цикла, который выполняет итерации через список. Если текущее число 0, я добавляю значение к новому Списку. После того, как Параллель для цикла завершается, я произвел размер списка. Размер должен всегда быть 1,000. Большую часть времени корректный ответ дан. Однако я видел, что происходят 3 возможных неправильных результата:
doubleList.Add(0.0);
doubleList.Add(0.0);
Сообщение для данного ArgumentException было: Destination array was not long enough. Check destIndex and length, and the array's lower bounds.
Что могло вызывать ошибки? Действительно ли это - ошибка .NET? Есть ли что-то, что я могу сделать для предотвращения этого?
Попробуйте код за себя. Если Вы не получаете ошибку, попробуйте ее несколько раз. Также обратите внимание, что Вы, вероятно, не будете видеть ошибок использовать одножильную машину.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ParallelTest
{
class Program
{
static void Main(string[] args)
{
List intList = new List();
List doubleList = new List();
for (int i = 0; i < 250; i++)
{
intList.Clear();
doubleList.Clear();
for (int j = 0; j < 10000; j++)
{
intList.Add(j % 10);
}
Parallel.For(0, intList.Count, j =>
{
if (intList[j] == 0)
{
doubleList.Add(0.0);
}
});
if (doubleList.Count != 1000)
{
Console.WriteLine("On iteration " + i + ": List size = " + doubleList.Count);
}
}
Console.WriteLine("\nPress any key to exit.");
Console.ReadKey();
}
}
}
Я ожидаю, что System.Collections.Generic.List не является потокобезопасным, что означает, что если вы попытаетесь одновременно Добавить
из двух разных потоков, все пойдет не так. Ах да, так сказано в документах .
Вы можете предотвратить это несколькими способами:
Это очень типичные проблемы, с которыми вы сталкиваетесь при работе с параллельным кодом данных.