4
我有一個約7030個項目的列表。我將列表中的項目保存到SQL Server中的表中。我想,我可以使用多線程來加速這個過程,但是,它出現了一個問題。將數據加載到SQL Server時出現C#多線程問題
上傳到數據庫的項目數量沒有變化,但是當我運行我的代碼後查詢表格中的記錄數時,它總是不同的,比如一次它會上傳6925,下次6831等我不明白爲什麼會發生這種情況。
在課堂上,我得到的數據
void DatabaseUploadMultiThreading()
{
DateTime dtUpload = Program.UploadDate();
int numThread = 8;
int splitNum = _holdingList.Count/numThread;
int leftOver = _holdingList.Count - (splitNum * (numThread - 1));
DatabaseWriter[] dbArray = new DatabaseWriter[numThread];
List<Holding>[] holdingArray = new List<Holding>[numThread];
Task[] taskDB = new Task[numThread];
for (int i = 0; i < holdingArray.Length; i++)
{
dbArray[i] = new DatabaseWriter(i + 1, dtUpload);
if (i == (numThread - 1))
holdingArray[i] = _holdingList.GetRange(i * splitNum, leftOver);
else
holdingArray[i] = _holdingList.GetRange(i * splitNum, splitNum);
}
for (int i = 0; i < taskDB.Length; i++)
taskDB[i] = Task.Factory.StartNew(dbArray[i].UploadHoldings, holdingArray[i]);
try
{
Task.WaitAll(taskDB); // wait for all the threads to complete
}
catch (AggregateException ex)
{
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
}
}
的DatabaseWriter類snipet
class DatabaseWriter : IDisposable
{
#region variable declaration
private SqlConnection _connection;
private SqlCommand _command;
private static readonly string _connectionString = "myConnectionString";
public void UploadHoldings(object objHoldingList)
{
List<Holding> holdingList = (List<Holding>)objHoldingList;
using (_connection = new SqlConnection(_connectionString))
{
_connection.Open();
DataReImported(_dtUpload);
for (int i = 0; i < holdingList.Count; i++)
{
string cmdText = "INSERT INTO HOLDINGS([FUND_CD], [SEDOLCHK], [NOMINAL], [CURR], [PRICE], [DATEU]) " +
"VALUES(@fundcode, @sedol, @nominal, @curr, @price, @dtUpload)";
_command = new SqlCommand(cmdText, _connection);
_command.Parameters.Add("@fundCode", SqlDbType.VarChar).Value = holdingList[i].FundCode;
_command.Parameters.Add("@sedol", SqlDbType.VarChar).Value = holdingList[i].IdSedol;
_command.Parameters.Add("@nominal", SqlDbType.Decimal).Value = holdingList[i].Nominal;
_command.Parameters.Add("@curr", SqlDbType.VarChar).Value = holdingList[i].Currency;
_command.Parameters.Add("@price", SqlDbType.Decimal).Value = holdingList[i].Price;
_command.Parameters.Add("@dtUpload", SqlDbType.Date).Value = _dtUpload;
_command.ExecuteNonQuery();
Console.WriteLine("Thread Number:" + _threadNum + " Security Number uploaded: " + i + " of " + holdingList.Count);
}
_connection.Close();
}
}
}
您是否考慮過[Bulk Insert](http://technet.microsoft.com/zh-cn/library/ms188365.aspx)?只需將所有數據寫入服務器可以訪問和導入的臨時文件即可。 – pstrjds
ExecuteNonQuery是否返回0?如果是這樣,這些就是你在數據庫中缺失的值。 –
既然你想優化,你有沒有考慮過構建'SqlCommand'及其params一次,然後簡單地更新每次執行的值,而不是重建每個記錄的整個'SqlCommand'層次結構? – LB2