ThreadPool.QueueUserWorkItem versus BeginExecuteNonQuery

天涯浪子 提交于 2019-12-11 12:15:01

问题


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

回答1:


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

p.s. this line in :

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



来源:https://stackoverflow.com/questions/24117762/threadpool-queueuserworkitem-versus-beginexecutenonquery

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!