Я разрабатываю программу на C #, которая вставляет около 100 000 строк в файл dbase версии 4 (* .dbf), используя драйвер vfpoledb.
Метод, который возвращает строку подключения, следующий:
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;
}
}
Этот сегмент запускается в трех потоках одновременно. Таким образом, данные вставляются в три файла dbase одновременно из 3 SqlDataReaders.
Моя проблема в том, что моя программа расходует около 50-100 МБ в минуту, и она увеличивается только до тех пор, пока я не закрою программу. Из-за этого в программе возникают исключения System.OutOfMemoryException, и ОС вскоре закрывает их. Я вижу, как использование файла подкачки в Диспетчере задач изменяется с 540 МБ до 2,2 ГБ.
Я сузил его до строки cmd.ExecuteNonQuery (); Если я закомментирую эту строку, программа будет работать с увеличением памяти примерно на 1 или 2 МБ.
Следовательно
- Может ли это быть из-за утечки памяти в драйвере VFPOledb? Я использую последнюю версию 9
- Если так, что я могу сделать, чтобы справиться с этим? (Оборачивая это как отдельный процесс, чтобы ОС убирала все утечки памяти при заманчивых звуках выхода, но это должно быть последним средством)
- Вы видите или знаете о какой-либо другой неисправности, которая может быть причиной этого?
- Смена драйвера может помочь, но драйвер Jet медленный, кропотливо медленный. Есть ли другой вариант для массовых вставок dbase? Я также задавал этот вопрос здесь Эффективный способ массовой вставки в файлы Dbase (.dbf)
Заранее спасибо.