我正在运行一个非常简单的函数,它可以批量读取文本文件中的行。每一行都包含一个sql查询,因此函数将获取指定数量的查询,对sql数据库执行这些查询,然后获取下一批查询,直到读取整个文件为止。问题是,随着时间的推移,对于非常大的文件,处理过程开始相当缓慢。我猜函数中的某个地方有内存泄漏,但无法确定它可能在哪里。此函数正在运行时,没有其他操作。我的编程技巧充其量是粗糙的,所以请对我放轻松。:)
for (int x = 0; x<= totalBatchesInt; x++)
{
var lines = System.IO.File.ReadLines(file).Skip(skipCount).Take(batchSize).ToArray();
string test = string.Join("\n", lines);
SqlCommand cmd = new SqlCommand(test.ToString());
try
{
var rowsEffected = qm.ExecuteNonQuery(CommandType.Text, cmd.CommandText, 6000, true);
totalRowsEffected = totalRowsEffected + rowsEffected;
globalRecordCounter = globalRecordCounter + rowsEffected;
fileRecordCounter = fileRecordCounter + rowsEffected;
skipCount = skipCount + batchSize;
TraceSource.TraceEvent(TraceEventType.Information, (int)ProcessEvents.Starting, "Rows
progress for " + folderName + "_" + fileName + " : " + fileRecordCounter.ToString() + "
of " + linesCount + " records");
}
catch (Exception esql)
{
TraceSource.TraceEvent(TraceEventType.Information, (int)ProcessEvents.Cancelling, "Error
processing file " + folderName + "_" + fileName + " : " + esql.Message.ToString() + ".
Aborting file read");
}
}
1条答案
按热度按时间jxct1oxe1#
你的代码有很多问题:
你从不放弃你的命令。这是odbc驱动程序的本机句柄,等待垃圾收集器处理它是非常糟糕的做法。
无论如何,你不应该单独发送这些命令。要么在一个命令中一次发送它们,要么使用事务将它们分组在一起。
这就是为什么随着时间的推移它变得越来越慢的原因:
File.ReadLines(file).Skip(skipCount).Take(batchSize)
会一遍又一遍地读取同一个文件,每次尝试都会忽略越来越多的行,因此随着被忽略(但已处理)的行数越来越大,会越来越慢。要修复#3,只需创建一次枚举器并成批迭代它。在纯c#中,可以执行以下操作:
或者,如果您正在使用morelinq(我推荐),可以这样做: