2012-02-03 59 views
1

是否有可能提取我的代碼中的代碼部分,並讓它在多個線程中運行?多線程,DataReaders和批量插入...這個應用程序可以多線程?

該應用程序在複製數據從一個FoxPro數據庫到我們的SQL服務器通過網絡(文件是相當巨大的,因此批量複製需要增量發生......

它的工作原理,但我想顛簸起來的速度的比特。

1)通過任一具有I標記在多個線程中運行,或者作爲替代的部分中,

2)通過在數據行的每一列不循環,

我去了第二個選項...(更新下面的代碼)

CODE

private void BulkCopy(OleDbDataReader reader, string tableName, Table table) 
    { 
     if (Convert.ToBoolean(ConfigurationManager.AppSettings["CopyData"])) 
     { 
      Console.WriteLine(tableName + " BulkCopy Started."); 
      try 
      { 
       DataTable tbl = new DataTable(); 
       foreach (Column col in table.Columns) 
       { 
        tbl.Columns.Add(col.Name, ConvertDataTypeToType(col.DataType)); 
       } 

       int batch = 1; 
       int counter = 0; 

       DataRow tblRow = tbl.NewRow(); 

       while (reader.Read()) 
       { 
        counter++;     
////This section changed 
         object[] obj = tblRow.ItemArray; 
         reader.GetValues(obj); 
         tblRow.ItemArray = obj; 
////********** 
        tbl.LoadDataRow(tblRow.ItemArray, true); 

        if (counter == BulkInsertIncrement) 
        { 
         Console.WriteLine(tableName + " :: Batch >> " + batch); 
         counter = PerformInsert(tableName, tbl, batch); 
         batch++; 
        } 
       } 

       if (counter > 0) 
       { 
        Console.WriteLine(tableName + " :: Batch >> " + batch); 
        PerformInsert(tableName, tbl, counter); 
       } 

       tbl = null; 
       Console.WriteLine("BulkCopy Success!"); 
      } 
      catch (Exception) 
      { 
       Console.WriteLine("BulkCopy Fail!"); 
      } 
      finally 
      { 
       reader.Close(); 
       reader.Dispose(); 
      } 
      Console.WriteLine(tableName + " BulkCopy Ended."); 
     } 
    } 

UPDATE 我去了第二個選項

我不知道,而同時內部(reader.Read())循環,我可以做下列。 I'T有助於大大提高應用程序的性能

while (reader.Read()) 
{ 
    object[] obj = tblRow.ItemArray; 
    reader.GetValues(obj); 
    tblRow.ItemArray = obj; 
    tbl.LoadDataRow(tblRow.ItemArray, true); 
} 

回答

1

這可能不是你後的答案,但你第一次嘗試運行在發佈模式的控制檯應用程序,只有一個try語句,並使用索引在讀者?由於SQL Server將成爲主要瓶頸,因此可能無法通過多線程來提高速度。

當然,如果您不太關心數據完整性(例如您的ID不是連續的),您可以更改插入的table locking類型,並旋轉3-4個線程以從表中的某些點讀取。

+0

我會嘗試高清所有的建議,爲興趣點,將你可以提供一個代碼示例,瞭解如何更改表鎖定類型,從c#..我現在是第一次聽說它,所以似乎有點太空時代:p(我會諮詢谷歌作爲好吧) – 2012-02-03 10:23:18

0

我不認爲你的用例會從平行的每個顯着受益。此外,實現您代碼中使用的OleDbReader的原因也很難。

但是你可以做的是在SQL Server需要插入數據的時候,在你的循環不會阻塞的新線程上安排插入。

您可以使用Task.Factory.StartNew()method。但是,這會使錯誤處理更加複雜一些,換句話說,當插入失敗時,您可能會處理更多的數據,或者在最糟糕的情況下,已經有另一個線程正在等待數據庫的新插入。

4

如果你把初學者的錯誤去掉了,那麼就不需要多線程了。到處都是緩慢的代碼。

tblRow [col.Name] =讀者[col.Name];

SLOW。切勿使用名稱 - 在循環外獲取索引,然後使用索引。該行對eery行有2(!)字典查找,比行處理花費更多的時間。 DataTables/DataSet開始時速度很慢(技術選擇不好),但是代碼很慢,下降。使用分析器查看其他不良元素。

+0

我知道它的鬆散性,儘管我不知道索引會給性能帶來好處,所以謝謝,我現在就試試看...至於數據表,SqlBulkCopy只允許對於數據表,數據行和datareaders(我不能使用,因爲一些重新電線導致整個交易失敗),這將是我的第一個選擇... – 2012-02-03 10:33:15

+1

+1首先對較小的優化進行整理。你可能發現你不需要使用多線程,如果你能以更快的速度獲得單線程版本 – 2012-02-03 10:34:30

+0

好吧,更新我的代碼使用索引,性能幾乎相同,我忘了提及即時通訊在每次傳球中做了20 000條記錄的批量插入,每張表格有+/- 5mil記錄和60多張表格......所以我知道在網絡上的表現不會很驚人......這就是爲什麼在我看來,要走的路線是將記錄添加到數據表中發生在多個線程中...再次,數據集wasnt我的第一選擇/路線我採取了...批量插入似乎要走的路,所以我把它完成工作...... – 2012-02-03 10:52:45

0

如果您使用.NET 4,你可以嘗試使用TPL,和foreach循環轉換成類似

Parallel.ForEach(table.Columns, col => {/*rest of function here */} 
+0

令人遺憾的是,主要問題完全被忽略了 - 你無法將無限廣告平分。 – TomTom 2012-02-03 10:54:43