Использование параллельных расширений или параллельного LINQ с LINQ Take - PullRequest
1 голос
/ 03 февраля 2011

У меня есть база данных с 5 миллионами строк.Я пытаюсь сгенерировать строки XML для базы данных и отправить их в службу.Вместо того, чтобы делать это по одному, служба поддерживает одновременное получение 1000 записей.На данный момент это довольно медленно, занимает более 10 секунд на 1000 записей (включая обратную запись в базу данных и загрузку в службу).

Я пытался заставить работать следующий код, но безуспешно... Я получаю сбой, когда я пытаюсь это сделать.Любые идеи?

    var data = <insert LINQ query here>
    int take = 1000
    int left = data.Count();

    Parallel.For(0, left / 1000, i =>
        {
            data.Skip(i*1000).Take(1000)...
            //Generate XML here.
            //Write to service here...
            //Mark items in database as generated.
        });
        //Get companies which are still marked as not generated.
        //Create XML.
        //Write to Service.

Я получаю сбой, сообщая мне, что индекс выходит за пределы.Если left равно 5 миллионам, число в цикле должно быть не более 5000. Если я умножу это снова на 1000, я не получу больше 5 миллионов.Я бы не возражал, если бы он работал некоторое время, а затем потерпел неудачу, но он просто не работает после SQL-запроса!

Ответы [ 2 ]

3 голосов
/ 03 февраля 2011

Я думаю, что вам не нравится ваше последнее значение индекса - его нужно оставить / 1000 -1, а не оставить / 1000:

Parallel.For(0, left / 1000 - 1, i =>
        {
            data.Skip(i*1000).Take(1000)...
            //Generate XML here
            //Write to Service here...
            //mark items in DB as generated
        });
2 голосов
/ 03 февраля 2011

Я подозреваю, что ошибка индекса вне границ вызвана кодом, отличным от того, что отображается в данный момент.

При этом, это может быть обработано намного более чистым способом.Вместо того, чтобы использовать этот подход, вы должны рассмотреть возможность переключения на с помощью пользовательского разделителя .Это будет значительно более эффективным, так как каждый вызов Skip / Take будет вызывать переоценку вашей последовательности.

...