VFPOledb драйвер Возможная утечка памяти? - PullRequest
0 голосов
/ 25 апреля 2011

Я разрабатываю программу на 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 МБ.

Следовательно

  1. Может ли это быть из-за утечки памяти в драйвере VFPOledb? Я использую последнюю версию 9
  2. Если так, что я могу сделать, чтобы справиться с этим? (Оборачивая это как отдельный процесс, чтобы ОС убирала все утечки памяти при заманчивых звуках выхода, но это должно быть последним средством)
  3. Вы видите или знаете о какой-либо другой неисправности, которая может быть причиной этого?
  4. Смена драйвера может помочь, но драйвер Jet медленный, кропотливо медленный. Есть ли другой вариант для массовых вставок dbase? Я также задавал этот вопрос здесь Эффективный способ массовой вставки в файлы Dbase (.dbf)

Заранее спасибо.

1 Ответ

1 голос
/ 27 апреля 2011

После многих попыток я обернул кусок кода в отдельный процесс, чтобы очистить ОС после его выхода. Это было лучшее решение, которое я мог найти.

...