繁体   English   中英

ThreadPool.QueueUserWorkItem与BeginExecuteNonQuery

[英]ThreadPool.QueueUserWorkItem versus BeginExecuteNonQuery

由于在数据库表上安排了清理任务,因此使用简单的插入方法有时会超时而导致问题。 该任务每十分钟运行一次,在执行过程中,由于“等待操作超时”,我的代码经常在事件日志中记录一个错误。

我正在考虑的解决方案之一是使调用存储过程的代码异步,为了做到这一点,我首先开始研究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();
         }
      }
  });

我有几个问题,其中一些是假设:

由于我的insert方法的签名无效,因此我假定调用它的代码不等待响应。 这个对吗?

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

为何BeginExecuteNonQuery不运行存储过程? 我的代码错了吗?

可能您没有在连接字符串中添加Asynchronous Processing=True

另外-可能存在这样的情况,当来自sql的响应准备就绪时-asp.net响应已经发送。

这就是为什么需要使用的原因: Page.RegisterASyncTask (+ AsyncTimeout)

(如果使用webform异步页面,则应添加页面指令: Async="True"

ps这行在:

System.Threading.ThreadPool.QueueUserWorkItem在asp.net应用程序中很危险。 您应该注意,响应尚未发送。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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