2010-07-19 49 views
2

我bugfixing別人的代碼,它需要年齡在下面的代碼返回完整的數據集:如何使用ThreadPool並行化數據庫查詢?

DataTable dt = someLib.GetDataTable("EXEC [dbo].[CMS_Content_GetAllContents]"); 

// Copy the DataTable data to list. 
foreach (DataRow dr in dt.Rows) 
{ 
    ContentInfo aContentDetail = new ContentInfo(
      (int)dr["ID"], 
      (string)dr["ContentName"], 
      getCategories((int)dr["ID"]), 
      null, 
      (string)dr["Publisher"], 
      (string)dr["Price"], 
      false); 

    contentInfoList.Add(aContentDetail); ; 
} 

private string getCategories(int ContentID) 
{ 
    String categories = String.Empty; 
    String query = String.Format("EXEC [dbo].[CMS_Content_GetContentCategories] @ID = {0}", ContentID); 

    DataTable dt = clsGlobal.GetDataTable(query); 

    foreach (DataRow dr in dt.Rows) 
    { 
     categories = String.Concat((string)dr["ShortDescription"] + ", ");     
    } 

    if (categories.EndsWith(", ")) 
     categories = categories.TrimEnd(new char[] { ',', ' ' }); 

    return categories; 
} 

這是可悲的,因爲有超過1000行的數據表dt和我不能用它處理存儲過程級別!

我只是想知道如果我可以將getCategories(int)打電話,以便它可以並行但不知道如何將字符串返回給調用者?

或者,使用Threadpool是不是一個好主意,因爲我聽說Threadpool的工作線程不適用於長時間運行的查詢,如DB調用,因爲IOCompletion端口線程可能無法及時返回,因此工作人員可能會被阻止因爲那個?

任何幫助表示讚賞。

+0

這是一個爛攤子我負責的,儀式? – Chris 2010-07-19 05:34:27

+1

因爲我不確定,所以我沒有發佈答案,但我認爲使用線程做這件事不是個好主意。相反,如果我面對這個問題,我會首先分析找到瓶頸(有些東西可能在您發佈的內容中花費很高),然後如果是DB,我會考慮將GetCategories調用轉換爲一個帶有ID數組的單個調用 - 在代碼中進行類別關聯可能會快很多,而不是在for循環中調用多個數據庫。 – 2010-07-19 05:41:51

+0

您是否在等待要返回的類別時說要執行其他任務?如果沒有,請詳細說明。 – Gabe 2010-07-19 05:43:41

回答

1

恐怕線程不是這種情況下的答案(在線程池中或線程池中)。修復對數據庫的1000個調用。您可能會優化少量用戶的響應速度,但響應時間仍然非常令人痛苦,並且您的應用將以非常低的負載下降。

我不知道你有多大的控制對數據庫的,所以這裏有一些想法,跨越幾個層次:

  1. 拉與內容的類別。你可以創建一個函數來給字符串分隔它們,或者使用一個在一次調用中返回多個數據集的過程。
  2. 立即加載所有類別,並將數據放在內存中
  3. 更改您的UI,以便一次不使用1000個CMS項目。傳呼什麼的。

祝你好運。

+0

是的,的確,UI線程需要10多分鐘才能回覆響應。 想想我會從上面的答案中拿第二名,然後用新的商店流程進行黑客入侵。只是想完成並完成。非常感謝。 也許是時候找一份新工作了! :-) – Chris 2010-07-19 05:51:58

+0

一個他們會給你炸薯條的地方。 :-) – 2010-07-19 11:55:30

0

雖然,問題已經答案。但是,這可能會有所幫助。

您可以在工作線程中「移動」您的代碼並讓它運行。您也可以創建添加事件,只要線程完成工作,它就會讓您知道。通過這種方式,您可以繼續(或將進度條移至最後,如果有的話),以及其餘的工作。

  1. Here是你如何使用線程。
  2. 這是what I love,迄今。

作爲一個方面說明,我相信這可以在SP中完成(如果您可以共享查詢);因此我會創建一個SP來獲取內容詳細信息,併爲每個ContentDetailID準備一個以逗號分隔的類別列表,然後返回我的結果。

所以,您的通話將只是:

DataTable dt = someLib.GetDataTable("EXEC [dbo].[CMS_Content_GetAllContents_Ex]");//Note the _EX in the sp name (0: 
相關問題