2011-02-03 71 views
1

我有一個數據庫,其中有大約500萬行。我正在嘗試爲數據庫生成XML字符串並將它們推送到服務。該服務一次不支持一次,而是一次支持1000條記錄。目前,這是非常緩慢的,每1000條記錄佔用10秒鐘(包括寫回數據庫和上傳到服務)。在LINQ中使用並行擴展或並行LINQ取

我試圖讓下面的代碼工作,但失敗了......我嘗試它時遇到了崩潰。有任何想法嗎?

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是500萬,循環中的數字應該不超過5000.如果我再次乘以1000,我不應該超過500萬。我不介意它是否有效,然後失敗,但它只是在SQL查詢後失敗!有任何想法嗎?

+1

「索引超出範圍」異常告訴我,問題可能不是直接在您包含的代碼中。你能否提供一些關於數據查詢的更多信息,以及在跳過/取回之後你做了什麼?如果可能的話,簡化你自己的代碼,直到你有一個導致異常的最基本的例子,然後發佈。同時告訴我們錯誤實際發生在哪一行。 – StriplingWarrior 2011-02-03 17:33:55

+0

看看我的答案 - 您的代碼中存在一個錯誤 – Andrey 2011-02-03 17:41:54

+0

感謝評論小組成員。 (data.Skip(i * 1000).Take(1000)。似乎@Andrey在我的代碼中發現了一個錯誤...看到下面的答案... – TiernanO 2011-02-04 09:37:50

回答

2

我懷疑索引越界的錯誤是由其他代碼引起的比當前顯示的要多。

這就是說,這可以以更清潔的方式處理。不要使用這種方法,你應該考慮切換到using a custom partitioner。這將大大提高效率,因爲每次撥打Skip/Take都會強制重新評估您的序列。

3

我認爲它不喜歡你的最後一個索引值 - 它應該留給/ 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 
     });