简体   繁体   中英

ThreadPool.QueueUserWorkItem versus BeginExecuteNonQuery

I have a problem at work with a simple insert method occasionally timing out due to a scheduled clean-up task on a database table. This task runs every ten minutes and during its execution my code often records an error in the event log due to 'the wait operation timed out'.

One of the solutions I'm considering is to make the code calling the stored procedure asynchronous, and in order to do this I first started looking at the BeginExecuteNonQuery method.

I've tried using the BeginExecuteNonQuery method but have found that it quite often does not insert the row at all. The code I've used is as follows:

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();
}

Obviously, I'm not expecting an instant insert but I am expecting it to be inserted after five minutes on a low usage development database.

I've now switched to the following code , which does do the insert:

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();
         }
      }
  });

I've got a few questions, some of them are assumptions:

As my insert method's signature is void, I'm presuming code that calls it doesn't wait for a response. Is this correct?

Is there a reason why BeginExecuteNonQuery doesn't run the stored procedure? Is my code wrong?

Most importantly, if I use the QueueUserWorkItem (or a well-behaved BeginExecuteNonQuery) am I right in thinking this will have the desired result? Which is, that an attempt to run the stored procedure whilst the scheduled task is running will see the code executing after the task completes, rather than its current timing out?

Edit

This is the version I'm using now in response to the comments and answers I've received.

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);

Is there a reason why BeginExecuteNonQuery doesn't run the stored procedure? Is my code wrong?

Probably you didn't add the Asynchronous Processing=True in the connection string.

Also - there could be a situation that when the reponse from sql is ready - the asp.net response has already sent.

that's why you need to use : Page.RegisterASyncTask (+AsyncTimeout)

(if you use webform asynchronous pages , you should add in the page directive : Async="True" )

ps this line in :

System.Threading.ThreadPool.QueueUserWorkItem is dangerouse in asp.net apps. you should take care that the response is not already sent.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM