Ошибка: «Невозможно установить командный текст, пока активен источник данных» с ExecuteNonQuery () - PullRequest
5 голосов
/ 29 сентября 2011

Я слушаю поток данных и сохраняю данные как операторы вставки в ConcurrentQueue и вставляю данные с массовой вставкой, используя System.Threading.Timer с интервалом 1000.Весь сценарий выполняется в статическом классе.Вот код:

static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    if (queryQueue.IsEmpty)
        return;
    string text = "";
//bulkBuilder is StringBuilder.
//queryQueue is ConcurrentQueue
    bulkBuilder.AppendLine("PRAGMA synchronous = 0;PRAGMA count_changes = FALSE;PRAGMA journal_mode=OFF;Begin;");
    while (queryQueue.TryDequeue(out text))
    {
        bulkBuilder.Append(text);
        bulkBuilder.AppendLine(";");
    }
    bulkBuilder.AppendLine("Commit;");

    try
    {
        sqlCommand.CommandText = bulkBuilder.ToString();
        sqlCommand.ExecuteNonQuery();
    }
    catch (System.Exception ex)
    {
        Console.WriteLine("Error while inserting Data : " + ex.Message);
    }
    finally
    {
        bulkBuilder.Clear();
    }

}

Забавно, sqlCommand используется только для вставки, только до ExecuteNonQuery() в этом таймере.Время от времени появляется сообщение об ошибке: «Невозможно установить командный текст, когда активен считыватель данных».Это бессмыслица, так как этот код не имеет ничего общего с внутренним SQLiteDataReader в sqlCommand.

Как мне избавиться от этой ошибки?

1 Ответ

13 голосов
/ 29 сентября 2011

Я бы создал новый SqlCommand (или любой другой тип sqlCommand) для каждого оператора SQL.Пусть пул подключений сделает все это эффективным - каждый раз, когда вам нужно что-то сделать с базой данных:

  • Создайте и откройте соединение
  • Создайте команду
  • Выполните команду
  • Удалите команду и соединение (с помощью оператора using)

Таким образом, вы не сможете получить локальное состояние одной команды, влияющее на другую команду.кроме как из-за нехватки места в пуле соединений и т. д.

Разработчики часто пытаются оптимизировать, используя одно соединение (и, возможно, команду) снова и снова, но это ложная экономия и приводит к таким проблемам, какВы показали.

...