存储过程未完成,但 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 为“真”的主要内容,如果未能解决你的问题,请参考以下文章

oracle存储过程提示编译完成但存在错误,如何查看错误

未调用 Firebase 存储完成处理程序

存储过程或函数需要未提供的参数

警告执行已完成,带有警告存储过程

PL/SQL 匿名块已完成但未显示结果

带有隐式游标的过程正在编译但未打印