sql—c中简单批处理文件处理函数中可能存在的内存泄漏#

vatpfxk5  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(322)

我正在运行一个非常简单的函数,它可以批量读取文本文件中的行。每一行都包含一个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");       
        }
    }
jxct1oxe

jxct1oxe1#

你的代码有很多问题:
你从不放弃你的命令。这是odbc驱动程序的本机句柄,等待垃圾收集器处理它是非常糟糕的做法。
无论如何,你不应该单独发送这些命令。要么在一个命令中一次发送它们,要么使用事务将它们分组在一起。
这就是为什么随着时间的推移它变得越来越慢的原因: File.ReadLines(file).Skip(skipCount).Take(batchSize) 会一遍又一遍地读取同一个文件,每次尝试都会忽略越来越多的行,因此随着被忽略(但已处理)的行数越来越大,会越来越慢。
要修复#3,只需创建一次枚举器并成批迭代它。在纯c#中,可以执行以下操作:

using var enumerator = File.ReadLines(file).GetEnumerator();

for (int x = 0; x<= totalBatchesInt; x++)
{
    var lines = new List<string>();
    while(enumerator.MoveNext() && lines.Count < batchSize)
        list.Add(enumerator.Current);
    string test = string.Join("\n", lines);
    // your code...
}

或者,如果您正在使用morelinq(我推荐),可以这样做:

foreach(var lines in File.ReadLines(file).Batch(batchSize))
{
    // your code...
}

相关问题