0

我在.NET 4.0中的工作和我的代碼應該這樣做:使用Parallel.ForEach和Tasks.Factory.StartNew數據庫插入/更新用

我有暴露給用戶的WebAPI。在這我有一個對象的集合。基本上是一個包含一些對象的ConcurrentBag。我必須迭代該集合中的每個對象,然後在數據庫中插入/更新其數據。對象的數量可以很高(200-300)。除此之外,如果可以有多個使用我的API的併發用戶。

現在,插入/更新用是作爲康涅狄格州的數據庫,這使得這個過程非常緩慢的做出每一個記錄很慢。不幸的是我不能改變這個邏輯。

爲了提高我使用的,而不是常規的foreach Parallel.ForEach因爲每個迭代不同勢性能。另外,我在db

這裏創建每次插入一個單獨的任務是我的代碼

var tasks = new List<Task>(allRecordings.Count);//Creating a Task List 
Parallel.ForEach(allRecordings, recording => 
     { 
      var recordingItem = recording; 
      //Lines oF Code 
      //           

     if (some Conditions){ 
      var task = Task.Factory.StartNew(
           () => SaveRecordingDetailsToDb(ref recordingItem, device.Locale)); 
      recording.Title = recordingItem.Title; 
      recording.ProgramId =recordingItem.ProgramId; 
      recording.SeriesId = recordingItem.SeriesId; 
      tasks.Add(task);//Adding Task to List 
      } 
     }); 
     Task.WaitAll(tasks.ToArray()); //Waiting for all Tasks to complete before going back to main 
              Function 
} 

可以MemoryLeak當有消費這一相同的API 另外多個併發請求發生在上述區塊,將使用Parallel.ForEach比普通的ForEach更好。

+3

「作爲康涅狄格州的數據庫,這使得這個過程非常緩慢的做出每個記錄」 - 這聽起來不太可能,如果你要使用正規ADO.NET的主要數據庫;自動連接池通常支持開箱即用。目前正在採取什麼樣的時間?我不確定''Parallel.ForEach'在這裏可以幫助你(它甚至可能是積極無用的,即使它變得更糟) –

+0

所以這裏發生的是當SaveRecordingDetailsToDb被調用時,首先它從MongoDB中檢索一些信息,然後執行在MS SQL Server中存儲過程。這是一個遺留代碼:( –

+1

好吧,它的SQL Server部分應該支持連接池。我不能評論mongo。回到問題:你有*理由*認爲它可能導致某種泄漏? –

回答

0

的TPL(任務並行庫)是專門爲計算量限制的操作設計的,爲此,可以並行地完成(如在不同的CPU內核的計算)的操作。在你的情況下,你寫入數據庫,所以,基本上你寫了一些文件系統,即這是IO操作。從純並行性的角度來看,IO操作不能並行執行。如果您同時運行多個IO操作,它們將會簡單地相互中斷,因此需要更多時間才能完成與逐個運行的比較。當然,數據庫服務器應該以某種方式處理這種情況,但它不會比一個接一個地向它發送請求更快,更可能的是,它會更慢。

+0

我做了一些基準測試,我發現使用TPL實際上可以減少三分之一的時間,而這裏的評論暗示,它會變得更糟,讓我完全糊塗是否堅持是否 –

+0

數據庫服務器可能會進行一些優化,例如將請求結合到數據庫。 –

相關問題