c # Ошибка параллельного цикла - PullRequest
4 голосов
/ 26 ноября 2010

Кто-нибудь может помочь? Когда я пишу этот код и запускаю. Программа показывает мне сообщение об ошибке «Уже существует открытый DataReader, связанный с этой командой, который должен быть закрыт первым».

Это мой код.

Parallel.For(0, MthRange, i => {
    PSUpfrontFeeForMonth[i] = CommissionSummary
        .Where(s => s.TransDate == oReportCommonFilter.fromDate.AddMonths(i))
        .Sum(s => s.PSUpfrontFee);

    if (!PSUpfrontFeeForMonth[i].HasValue)
    {
        PSUpfrontFeeForMonth[i] = 0;
    }
});

Спасибо.

С уважением, Jane

Ответы [ 3 ]

4 голосов
/ 26 ноября 2010

Распараллеливание запроса к базе данных совершенно неверно по следующим причинам:

  1. Запрос выдан против sql от каждый процессор так много данных читатели будут открыты -> 'ошибка'
  2. На самом деле не достигается прирост производительности программа становится медленнее, потому что каждый процессор пытается подключиться к база данных и нет параллели обработка фактически выполняется, так как все обработка запросов выполняется в sql! так нормальный последовательный запрос быстрее в это дело.
1 голос
/ 26 ноября 2010

Если вам действительно нужно открыть несколько соединений с базой данных одновременно (как другие заявили, что это не всегда хорошая идея), то вы обычно можете указать в строке соединения, что это необходимо.

Типичный сценарий, в котором я использовал это для использования DataReader для потоковой передачи строк из таблицы базы данных (так как я не знаю, сколько строк мне нужно в расширенной версии) и где мне затем нужно сделать дополнительные запросы к другим таблицы базы данных. Я делаю это, а не один запрос, так как для этого потребуется несколько сложных объединений, и у моего приложения есть хороший уровень кэширования для сокращения запросов к базе данных.

Для Microsoft SQL Server вы добавляете MultipleActiveResultSets=True; в строку подключения

0 голосов
/ 26 ноября 2010

Я думаю, что это связано с тем, как PSUpfrontFeeForMonth внутренне работает с использованием считывателей данных.

Поскольку я понятия не имею, как это работает, в первую очередь я бы попытался инициализировать PSUpfrontFeeForMonth внутри цикла.Может быть, это обеспечит выделенный читатель данных для каждой итерации.

...