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

C# c中简单批处理文件处理函数可能存在内存泄漏,c#,sql,memory-management,memory-leaks,C#,Sql,Memory Management,Memory Leaks,我正在运行一个非常简单的函数,它可以批量读取文本文件中的行。每一行都包含一个sql查询,因此函数将获取指定数量的查询,对sql数据库执行查询,然后获取下一批查询,直到读取整个文件。问题是,随着时间的推移,对于非常大的文件,处理过程开始显著减慢。我猜函数中某处有内存泄漏,但无法确定它可能在哪里。当此函数运行时,没有其他操作。我的编程技能充其量只是粗糙的,所以请对我宽容一点 for (int x = 0; x<= totalBatchesInt; x++) { var

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

您的代码有很多错误:

你从不放弃你的命令。这是ODBC驱动程序的本机句柄,等待垃圾收集器处理它是非常糟糕的做法

无论如何,您不应该单独发送这些命令。可以在一个命令中一次性发送它们,也可以使用事务将它们组合在一起

这就是它随时间变慢的原因:File.ReadLinesfile.SkipskipCount.TakebatchSize会反复读取同一个文件,每次尝试都会忽略越来越多的行,因此随着被忽略但已处理的行数越来越大,速度越来越慢

要修复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...
}

您的代码有很多错误:

你从不放弃你的命令。这是ODBC驱动程序的本机句柄,等待垃圾收集器处理它是非常糟糕的做法

无论如何,您不应该单独发送这些命令。可以在一个命令中一次性发送它们,也可以使用事务将它们组合在一起

这就是它随时间变慢的原因:File.ReadLinesfile.SkipskipCount.TakebatchSize会反复读取同一个文件,每次尝试都会忽略越来越多的行,因此随着被忽略但已处理的行数越来越大,速度越来越慢

要修复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...
}

. 但我怀疑这是你问题的核心。这可能不是核心,但现在你指出了,这肯定是个问题。谢谢你的意见。。但我怀疑这是你问题的核心。这可能不是核心,但现在你指出了,这肯定是个问题。谢谢你的投入。谢谢你的耐心,这对3个人来说非常有意义。对于2,分多批发送的原因是,由于服务器正在接收其他并发请求,因此不会使服务器过载。我通常一次发送一个包含1000行SQL查询的命令。也许我误解了你在说什么。1和3看起来很明显,因为你指出了它们。我将尽快实施这些更改。非常感谢!!根据你的推荐,我选择了Morelinq,让我的生活变得轻松多了。性能大大提高。谢谢谢谢你的耐心,这对我来说非常有意义。对于2,分多批发送的原因是,由于服务器正在接收其他并发请求,因此不会使服务器过载。我通常一次发送一个包含1000行SQL查询的命令。也许我误解了你在说什么。1和3看起来很明显,因为你指出了它们。我将尽快实施这些更改。非常感谢!!根据你的推荐,我选择了Morelinq,让我的生活变得轻松多了。性能大大提高。谢谢