我知道某个地方我可能忽略了某些东西,但我正在尝试修复一个我没有开发但通常不会维护的应用程序,所以如果我直截了当地犯错,请提前原谅我。
这个web-app目前存在一个问题,即在执行某个函数时导致超时,我已将其追溯到一件事,它正在执行存储过程并期望存储过程返回#of受影响的行,这一切都很好,花花公子。但是,此存储过程至少运行50秒并导致超时。此外,我不希望UI在50秒内挂起,而这只是根据已更改的信息更新数据库中的某些状态字段,它返回的内容对最终用户没用,所以它只是需要被触发和忘记,以便用户可以继续使用该应用程序。
我已经尝试过创建任务和创建线程,但由于某种原因,该函数仍然坚持等待此操作完成。
这是调用存储过程的函数:
public static void UpdateComputerStatusByApplicationID(int ApplicationID)
{
using (SqlConnection Conn = new SqlConnection(GlobalMethods.CONNECTION_STRING))
{
SqlCommand Cmd = new SqlCommand("UpdateComputerStatusByApplicationId", Conn);
Cmd.CommandType = CommandType.StoredProcedure;
Cmd.Parameters.Add("@applicationid", SqlDbType.Int).Value = ApplicationID;
Conn.Open();
Cmd.ExecuteNonQuery();
Conn.Close();
}
}
异常来自Cmd.ExecuteNonQuery();这是一个超时异常。
这是我从函数中将其称为任务的地方:
public void UpdateApplication(a_Applications newApplication, XPToWin7 xpToWin7)
{
try
{
var orginalApplication = GetApplication(newApplication.AutoNumber);
ObjectContext.ApplyCurrentValues(orginalApplication.EntityKey.EntitySetName, newApplication);
if (xpToWin7 != null)
{
UnlinkXPAppWithWin7App(orginalApplication.AutoNumber);
LinkXPAppWithWin7App(orginalApplication.AutoNumber, xpToWin7);
}
Task UpdateComputerStatus = Task.Factory.StartNew(() =>
{
DAL.UpdateComputerStatusByApplicationID(orginalApplication.AutoNumber);
}, TaskCreationOptions.LongRunning);
SaveChanges();
}
catch (Exception ex)
{
throw new Exception("Exception when updating the application" + ex.Message, ex);
}
}
我不确定我哪里出错了,或者为什么它没有按预期工作但是当这个函数被调用时它只是在UI中挂起,直到它抛出一个来自cmd.ExecuteNonQuery的内部异常( );
非常感谢任何帮助或建议!
答案 0 :(得分:5)
从客户端异步调用存储过程可能是一个很大的痛苦 - 您必须考虑多个线程,BeginXXX和EndXXX方法,使用回调并且应用程序必须保持活动状态直到它完成 - 否则可能会发生回滚。是的,这是可能的 - 看看这个答案:Asynchronous call of a SQL Server stored procedure in C#
可能有一种更简单的方法 - 为什么不让存储过程异步?使用Service Broker,您可以创建一个激活存储过程的简单队列。调用存储过程不必等待响应。它只是创建一个新的会话,传递请求的详细信息并立即返回。激活的存储过程是所有繁重的工作,可能需要几秒钟,几分钟或几小时 - 但这对UI来说并不重要,因为它不会等待响应。即使您的UI关闭,异步存储过程也会一直运行直到完成。
http://rusanu.com/2009/08/05/asynchronous-procedure-execution/