gpt4 book ai didi

将数据加载到 SQL Server 时的 C# 多线程问题

转载 作者:行者123 更新时间:2023-11-30 12:45:48 25 4
gpt4 key购买 nike

我有一个包含大约 7030 项的列表。我将列表中的项目保存到 SQL Server 中的表中。我想,我可以使用多线程来加速这个过程,它确实做到了,但是,出现了一个问题。

上传到数据库的项目数没有变化,但是当我运行我的代码后查询表中的记录数时,它总是不同的,说一次上传了 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 类代码片段

 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();
}
}



}

最佳答案

我建议这不是使用多个任务的最佳位置。上面显示的代码效率有点低,将其拆分为 Task 对象并并行运行它们,在许多情况下只会使它们彼此绊倒并减慢您的速度或导致其中一个不执行。就像三个臭皮匠同时试图冲进一扇门。

按照上面其他回答者的建议进行基本的、明显的优化,即只创建一次 SqlCommand,并在循环内进行绝对最小化(或者尝试批量加载方法)。并检查 ExecuteNonQuery 返回的值以验证写入的记录数。

关于将数据加载到 SQL Server 时的 C# 多线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22840303/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com