【发布时间】: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);
【问题讨论】:
标签: c# .net sql-server sqlcommand iasyncresult