многопоточная ошибка .net Parallel.For

Мне нужно вычислить расстояния между примерно 26 000 компаний и найти медиану всех расстояний. Однако программа выдает следующее исключение:

at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Task.Wait()
at System.Threading.Tasks.Parallel.ForWorker[TLocal](Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Func`4 bodyWithLocal, Func`1 localInit, Action`1 localFinally)
at System.Threading.Tasks.Parallel.For(Int32 fromInclusive, Int32 toExclusive, Action`2 body)
at DataHelper.FindMediumBase.CountDistancesPerKilometer()

Это моя программа:

protected void CountDistancesPerKilometer()
{
    try
    {
        int EnterprisesCount = enterprises.Count;
        Stopwatch watch = new Stopwatch();
        watch.Start();
        Parallel.For(0, enterprises.Count, (i, loopStateOut) =>
        {
            Enterprise eOut = enterprises.ElementAt(i);
            for (int j = i + 1; j < enterprises.Count; j++)
            {
                Enterprise eIn = enterprises.ElementAt(j);
                double distance = Math.Sqrt((eOut.Point.X - eIn.Point.X) * (eOut.Point.X - eIn.Point.X) +
                                            (eOut.Point.Y - eIn.Point.Y) * (eOut.Point.Y - eIn.Point.Y)) / 1000;

                if (0 == distance)
                    continue;
                else
                    DistanceFiles[(int)distance].FileRowCount++;
            }
        });
        watch.Stop();
        System.Console.WriteLine(watch.ElapsedTicks);
    }
    catch (Exception ex)
    {
        Log.WriteError(ex.StackTrace);
    }
}

PS:

enterprises: List<Enterprise>
DistanceFiles : ConcurrentDictionary<int, DistanceFile>

person mzl9039    schedule 28.03.2016    source источник
comment
DistanceFiles[(int)distance].FileRowCount++; — Вы уверены, что distance — существующий ключ в словаре?   -  person Yuval Itzchakov    schedule 28.03.2016
comment
Что такое DistanceFiles?   -  person Dmitry Bychenko    schedule 28.03.2016
comment
@DmitryBychenko В конце вопроса: ConcurrentDictionary<int, DistanceFile>   -  person Yuval Itzchakov    schedule 28.03.2016
comment
Есть ли у вас исключение в последовательной версии вашего кода (т. е. Parallel.For изменено на for(...))   -  person Dmitry Bychenko    schedule 28.03.2016
comment
при этом я помню, что максимальное расстояние меньше 5000 километров, но я постараюсь сделать словарь больше @YuvalItzchakov   -  person mzl9039    schedule 28.03.2016
comment
Исключение не возникает, если я использую for() {}, но для завершения вычисления потребуется более 16 часов, поэтому я использую Parallel.For. но сейчас не могу найти возможные причины@DmitryBychenko   -  person mzl9039    schedule 28.03.2016
comment
@ mzl9039 mzl9039, пожалуйста, добавьте полную информацию об исключении, включая детали внутреннего исключения. Изменить Log.WriteError(ex.StackTrace); в Log.WriteError(ex.ToString()); или Log.WriteError(ex.Message); и добавить новые результаты к вопросу.   -  person Vadim Martynov    schedule 28.03.2016
comment
Это займет 16 часов? Я не вижу здесь ничего, что указывало бы на то, что это должно занять так много времени! Однако вы можете столкнуться с проблемой, из-за которой вам может потребоваться заблокировать обновление файлов расстояний. Хотя я не вижу, что вы определили как   -  person BugFinder    schedule 28.03.2016
comment
там около 26 000 компаний, так что мне нужно рассчитать 26000 * 25999/2 расстояний, это занимает много времени @BugFinder   -  person mzl9039    schedule 28.03.2016


Ответы (1)


Вы вызываете ConcurrentDictionary<TKey, TValue>.Item, который может вызвать KeyNotFoundException, если свойство получен, а ключ не существует в коллекции.

Измените код, чтобы убедиться, что элементы существуют в словаре:

if (0 == distance)
    continue;
else
{
    if(!DistanceFiles.ContainsKey((int)distance))
    {
        var distanceFile = GetDistanceFile(); // retrieve or create new instance of tDistanceFile here
        DistanceFiles,Add((int)distance, distanceFile);
    }
    DistanceFiles[(int)distance].FileRowCount++;
}
person Vadim Martynov    schedule 28.03.2016
comment
Ну, я не могу гарантировать, что все позиции компаний верны, поэтому ваш ответ, возможно, является правильной причиной! Попробую, спасибо большое!!!@Вадим Мартынов - person mzl9039; 28.03.2016