ThreadPool.QueueUserWorkItem против BeginExecuteNonQuery

1

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

Одно из решений, которое я рассматриваю, - сделать код, вызывающий хранимую процедуру асинхронным, и для этого я сначала начал искать метод BeginExecuteNonQuery.

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

SqlConnection conn = daService.CreateSqlConnection(dataSupport.DBConnString);
SqlCommand command = daService.CreateSqlCommand("StoredProc");

try {
    command.Connection = conn;

    command.Parameters.AddWithValue("page", page);
    command.Parameters.AddWithValue("Customer", customerId);

    conn.Open();

    command.BeginExecuteNonQuery(delegate(IAsyncResult ar) {
        SqlCommand c = (SqlCommand)ar.AsyncState;

        c.EndExecuteNonQuery(ar);
        c.Connection.Close();
    }, command);

} catch (Exception ex) {
     LogService.WriteExceptionEntry(ex, EventLogEntryType.Error);
} finally {
     command.Connection.Close();
     command.Dispose();
     conn.Dispose();
}

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

Теперь я переключился на следующий код, который делает вставку:

System.Threading.ThreadPool.QueueUserWorkItem(delegate {
      using (SqlConnection conn = daService.CreateSqlConnection( dataSupport.DBConnString)) {
         using (SqlCommand command = daService.CreateSqlCommand("StoredProcedure")) {
             command.Connection = conn;

             command.Parameters.AddWithValue("page", page);
             command.Parameters.AddWithValue("customer", customerId);

             conn.Open();
             command.ExecuteNonQuery();
         }
      }
  });

У меня есть несколько вопросов, некоторые из них - предположения:

Поскольку моя подпись метода вставки недействительна, я предполагаю, что код, вызывающий ее, не ждет ответа. Это верно?

Есть ли причина, по которой BeginExecuteNonQuery не запускает хранимую процедуру? Является ли мой код неправильным?

Самое главное, если я использую QueueUserWorkItem (или хорошо выполненный BeginExecuteNonQuery), я прав, думая, что это будет иметь желаемый результат? Что означает, что попытка запуска хранимой процедуры во время выполнения запланированной задачи увидит, что код выполняется после завершения задачи, а не из-за ее текущего времени?

редактировать

Это версия, которую я использую сейчас в ответ на полученные комментарии и ответы.

SqlConnection conn = daService.CreateSqlConnection(
              string.Concat("Asynchronous Processing=True;",
              dataSupport.DBConnString));
SqlCommand command = daService.CreateSqlCommand("StoredProc");

command.Connection = conn;

command.Parameters.AddWithValue("page", page);
command.Parameters.AddWithValue("customer", customerId);

conn.Open();
command.BeginExecuteNonQuery(delegate(IAsyncResult ar) {
      SqlCommand c = (SqlCommand)ar.AsyncState;

      try {
          c.EndExecuteNonQuery(ar);
      } catch (Exception ex) {
           LogService.WriteExceptionEntry(ex, EventLogEntryType.Error);
      } finally {
          c.Connection.Close();
          c.Dispose();
          conn.Dispose();
      }

 }, command);
  • 0
    asp.net? ?????
  • 0
    Привет, Ройи, я добавил тег asp.net. Поблагодарить!
Показать ещё 4 комментария
Теги:
sql-server
threadpool

1 ответ

2
Лучший ответ

Есть ли причина, по которой BeginExecuteNonQuery не запускает хранимую процедуру? Является ли мой код неправильным?

Возможно, вы не добавили в строку подключения Asynchronous Processing=True.

Также - может быть ситуация, когда ответ от sql готов - ответ asp.net уже отправлен.

что вам нужно использовать: PageRegisterASyncTask (+AsyncTimeout)

(если вы используете асинхронные страницы webform, вы должны добавить в директиву страницы: Async="True")

ps эта строка в:

System.Threading.ThreadPool.QueueUserWorkItem является опасным в приложениях asp.net. вы должны позаботиться о том, чтобы ответ еще не был отправлен.

  • 0
    Вы правы, я не использовал Asynchronous Processing = True в моей строке подключения. Что касается Page.RegisterAsyncTask, я не думаю, что мне это нужно. Я использую HttpHandler, а не WebForm. Также я не жду ответа от SQL. Я просто делаю вставку.
  • 1
    HttpHandler, поэтому вы должны использовать IhttpAsyncHandler
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню