項目中需要讀取資料庫中的多張表。由於表的數據比較多,串列讀取時耗時比較多,所以對程式做了一點優化。 環境 .NET 3.5,SQL Server 2012,Visual Studio 2015 過程 項目中使用存儲過程串列地讀取資料庫,存儲過程接受同一個表變數作為參數。但是當在多線程中複製DataT ...
項目中需要讀取資料庫中的多張表。由於表的數據比較多,串列讀取時耗時比較多,所以對程式做了一點優化。
環境
.NET 3.5,SQL Server 2012,Visual Studio 2015
過程
項目中使用存儲過程串列地讀取資料庫,存儲過程接受同一個表變數作為參數。但是當在多線程中複製DataTable時有可能會出現異常,這是因為DataTable里的Rows不是線程安全的。不過微軟提供了一個叫SyncRoot的對象幫助我們在多線程時對DataTable進行操作。代碼如下
public static MyObject GetData(DataTable dataTable)
{
MyObject myObject = new MyObject();
DataTable tempTable = new DataTable();
// Lock the columns.
lock (dataTable.Columns.SyncRoot)
{
// Lock the rows.
lock (dataTable.Rows.SyncRoot)
{
tempTable = dataTable.Copy();
}
}
ReadFromDatabase(tempTable);
// Write your own code.
return myObject;
}
多線程下的使用方法如下
public static void Test()
{
DataTable dataTable = new DataTable();
MyObject obj = null;
Thread thread = new Thread(
() =>
{
obj = GetData(dataTable);
}
);
// Start a new thread.
thread.Start();
// Wait this thread terminated.
thread.Join();
}
可以改進的地方
調用 thread.Join() 時會阻塞當前線程,直到thread結束。某些情況還是會影響一部分性能的。
.NET 4.0以上提供了更加簡便的非同步操作和線程安全的數據結構。但是由於現有的項目是使用 .NET 3.5寫的,暫時也沒有辦法重構了
Reference
http://www.cnblogs.com/rui1236/p/4567420.html
https://stackoverflow.com/questions/1314155/returning-a-value-from-thread