我在使用简单的插入方法时遇到问题,因为数据库表上的计划清理任务偶尔会超时。此任务每十分钟运行一次,在执行期间,由于“等待操作超时”,我的代码通常会在事件日志中记录错误。
我正在考虑的一个解决方案是使代码调用存储过程异步,为了做到这一点,我首先开始查看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();
}
显然,我不期待即时插入,但我希望在低使用率开发数据库上五分钟后插入它。
I've now switched to the following code,它执行插入操作:
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);
答案 0 :(得分:2)
为什么BeginExecuteNonQuery没有运行存储的原因 程序?我的代码错了吗?
可能您没有在连接字符串中添加Asynchronous Processing=True
。
此外 - 可能存在这样的情况:当sql的响应准备就绪时 - asp.net响应已经发送。
这就是你需要使用的原因:Page.RegisterASyncTask(+ AsyncTimeout)
(如果你使用webform异步页面,你应该在页面指令中添加:Async="True"
)
P.S。这一行:
System.Threading.ThreadPool.QueueUserWorkItem
在asp.net应用程序中是危险的。你应该注意还没有发送回应。