C# VFPOledb驱动程序可能内存泄漏?
我正在用C语言开发一个程序,它使用vfpoledb驱动程序将大约100000行插入到版本4数据库文件(*.dbf)中 返回连接字符串的方法如下所示 internal string GetDBaseConnectionString(string path) { return "Provider=vfpoledb;Data Source=" + path + ";Collating Sequence=general;"; }C# VFPOledb驱动程序可能内存泄漏?,c#,memory-leaks,oledb,visual-foxpro,C#,Memory Leaks,Oledb,Visual Foxpro,我正在用C语言开发一个程序,它使用vfpoledb驱动程序将大约100000行插入到版本4数据库文件(*.dbf)中 返回连接字符串的方法如下所示 internal string GetDBaseConnectionString(string path) { return "Provider=vfpoledb;Data Source=" + path + ";Collating Sequence=general;"; } int
internal long Execute()
{
OleDbConnection con = null;
OleDbCommand cmd = null;
try
{
con = new OleDbConnection(AppSettings.Current.GetDBaseConnectionString(_dbfPath));
con.Open();
cmd = new OleDbCommand(_sql);
cmd.Connection = con;
cmd.CommandTimeout = AppSettings.Current.DefaultCommandTimeOutMinutes;
long rowIndex = 0;
int countInBatch = 0;
for (int i = 0; i < _reader.FieldCount; i++)
cmd.Parameters.Add(new OleDbParameter());
while (_reader.Read())
{
for (int i = 0; i < cmd.Parameters.Count; i++)
cmd.Parameters[i].Value = _reader.GetValue(i);
cmd.ExecuteNonQuery();
rowIndex += 1;
if (_progressChangeRowCount > 0)
{
countInBatch += 1;
if (countInBatch >= _progressChangeRowCount)
{
countInBatch = 0;
ProgressChangedEventArgs args = new ProgressChangedEventArgs(rowIndex);
this.OnProgressChanged(args);
}
}
}
_reader.Close();
con.Close();
con.Dispose();
cmd.Dispose();
return rowIndex;
}
catch (Exception ex)
{
if (con != null)
{
con.Close();
con.Close();
}
if (cmd != null)
cmd.Dispose();
if(_reader!= null)
_reader.Close();
throw ex;
}
}
内部字符串GetDBaseConnectionString(字符串路径)
{
返回“Provider=vfpoledb;Data Source=“+path+”;排序顺序=general;”;
}
执行插入的代码段如下所示:
internal string GetDBaseConnectionString(string path)
{
return "Provider=vfpoledb;Data Source=" + path + ";Collating Sequence=general;";
}
internal long Execute()
{
OleDbConnection con = null;
OleDbCommand cmd = null;
try
{
con = new OleDbConnection(AppSettings.Current.GetDBaseConnectionString(_dbfPath));
con.Open();
cmd = new OleDbCommand(_sql);
cmd.Connection = con;
cmd.CommandTimeout = AppSettings.Current.DefaultCommandTimeOutMinutes;
long rowIndex = 0;
int countInBatch = 0;
for (int i = 0; i < _reader.FieldCount; i++)
cmd.Parameters.Add(new OleDbParameter());
while (_reader.Read())
{
for (int i = 0; i < cmd.Parameters.Count; i++)
cmd.Parameters[i].Value = _reader.GetValue(i);
cmd.ExecuteNonQuery();
rowIndex += 1;
if (_progressChangeRowCount > 0)
{
countInBatch += 1;
if (countInBatch >= _progressChangeRowCount)
{
countInBatch = 0;
ProgressChangedEventArgs args = new ProgressChangedEventArgs(rowIndex);
this.OnProgressChanged(args);
}
}
}
_reader.Close();
con.Close();
con.Dispose();
cmd.Dispose();
return rowIndex;
}
catch (Exception ex)
{
if (con != null)
{
con.Close();
con.Close();
}
if (cmd != null)
cmd.Dispose();
if(_reader!= null)
_reader.Close();
throw ex;
}
}
内部长执行()
{
OLEDB连接con=null;
OleDbCommand cmd=null;
尝试
{
con=new-OleDbConnection(AppSettings.Current.getdbasconnectionstring(_-dbfPath));
con.Open();
cmd=新的OleDbCommand(_sql);
cmd.Connection=con;
cmd.CommandTimeout=AppSettings.Current.DefaultCommandTimeOutMinutes;
长行索引=0;
int countInBatch=0;
对于(int i=0;i<\u reader.FieldCount;i++)
cmd.Parameters.Add(新的OleDbParameter());
而(_reader.Read())
{
对于(int i=0;i0)
{
countInBatch+=1;
如果(countInBatch>=\u progressChangeRowCount)
{
countInBatch=0;
ProgressChangedEventArgs args=新的ProgressChangedEventArgs(行索引);
此.OnProgressChanged(args);
}
}
}
_reader.Close();
con.Close();
con.Dispose();
cmd.Dispose();
返回行索引;
}
捕获(例外情况除外)
{
如果(con!=null)
{
con.Close();
con.Close();
}
如果(cmd!=null)
cmd.Dispose();
如果(_reader!=null)
_reader.Close();
掷骰子;
}
}
此段在三个线程中同时运行。因此,数据从3个SQLDataReader同时插入到3个dbase文件中
我的问题是,我的程序每分钟消耗大约50-100 MB的内存,并且它只会在我关闭程序之前增加。由于此System.OutOfMemoryException在程序中引发,操作系统很快将其关闭。我可以看到任务管理器中的页面文件使用从540MB增加到2.2GB
我已将其缩小到cmd.ExecuteNonQuery()行;如果我注释掉这一行,程序执行时只增加大约1或2 MB内存。
因此
提前感谢。经过多次尝试后,我将代码打包到一个单独的进程中,以便操作系统在退出后进行清理。这是我能找到的最好的解决方案。你可以而且应该开始用
using(){}
blocks来简化它代码>应该是抛出代码>请添加_sql文本以及创建_读取器的方式/位置。创建_读取器并将其传递给该代码段所在类的构造函数。sql文本是一个简单的sql插入命令,通过查看读取器返回的列动态构建。这发生在该代码段所在的类的构造函数中,因此不会占用大量内存,因为它不重复;这条线修复了内存占用。因此,我确信这是vfpoledb驱动程序中的一个bug。