存储过程未完成,但 IAsyncResult.IsCompleted 为“真”
Posted
技术标签:
【中文标题】存储过程未完成,但 IAsyncResult.IsCompleted 为“真”【英文标题】:Stored Procedure not done, but IAsyncResult.IsCompleted is "true" 【发布时间】:2015-03-29 03:08:45 【问题描述】:我有一个我认为是供最终用户运行存储过程的简单程序,它可能需要相当长的时间才能运行。我想我可以使用异步连接,调用 Begin/EndExecuteNonQuery,并有一个计时器让用户知道它仍在运行。到目前为止,一切顺利。
如果某个参数为真,则被调用的存储过程将在最后执行另一个存储过程。看来,当这个辅助调用发生时,IsCompleted 变为“true”,即使它不是,然后程序会阻塞 EndExecuteNonQuery,直到第二个 SP 完成。虽然我不确定,但我想这是因为直接 SQL 进程完成了(因为它没有更多的事情要做,EXEC 调用是最后一行)但是一个子进程保持调用。
如何判断 SP 是否已完全完成? 我知道我没有完全理解 IAsyncResult.IsCompleted;我的印象是,当通话完全完成时,它变成了true
,但该链接中的以下声明让我不这么认为:
当此属性为真时,您可以假设丢弃任何 您分配给异步操作使用的资源。
所以它可能按预期工作,因为我可以安全地丢弃资源,即使完整的 SP 实际上并没有完成。如果是这种情况,是否有其他方法可以知道何时完成?我考虑过在另一个线程中使用普通的ExecuteNonQuery
(BackgroundWorker
?),但我想先确定我不会错过BeginXxx
/EndXxx
的内容。
我也愿意放弃 SqlCommand,这样程序就可以退出而无需等待 SP,因为第一个 SP 对最终用户来说是唯一真正重要的事情。
使用 .Net 4、MSSQL 2008 R2。
相关代码:
conn = new SqlConnection(@"Server=SERVERSQL;Initial Catalog=MyDatabase;User ID=MyUser;Asynchronous Processing=true");
SqlCommand cmd = new SqlCommand("OuterProcedure", conn);
cmd.CommandType = CommandType.StoredProcedure;
//[...]
IAsyncResult asyncObj = cmd.BeginExecuteNonQuery();
int count = 0;
int finalLine = Console.CursorTop;
while (!asyncObj.IsCompleted)
Console.SetCursorPosition(0, finalLine);
++count;
Console.WriteLine("Time taken (m:s): 0:1", Math.Floor((double)count / 60), (count % 60).ToString("D2"));
System.Threading.Thread.Sleep(1000);
Console.WriteLine("Complete");
int results = cmd.EndExecuteNonQuery(asyncObj);
【问题讨论】:
【参考方案1】:如果您使用 BeginExecuteNonQuery,您的代码在继续之前不会等待查询执行...它将标记为异步调用已完成。
如您所说,另一种方法是使用单独的 BackGroundWorker 来执行存储过程,如果您希望它在后台线程中执行。
参考this
【讨论】:
我想过;我试过让 SP 存储 EXEC 的返回值,然后是SELECT @result
,但这并没有改变任何东西。使用静态值代替@result
会起作用吗?
@Tukaro 看看这个:***.com/questions/14506871/…
如果您可以将第二个存储过程设为函数,则可以在 SELECT 语句中调用它,并将最终语句放入存储过程中。
啊,明白了。不,没有使它成为功能的现实方法。它做了一堆数字运算/比较,然后将结果存储到一个表中。花时间将其强制转换为函数比将 C# 的东西扔到另一个线程中要麻烦得多。以上是关于存储过程未完成,但 IAsyncResult.IsCompleted 为“真”的主要内容,如果未能解决你的问题,请参考以下文章