从Windows窗体异步执行存储过程然后断开连接?

我从我的应用程序调用存储过程,可能需要30分钟才能执行。

我不想让我的用户在整个时间段内打开应用程序。 所以我想打电话给sproc,让它飞起来,让他们关闭应用程序然后再回来。

我怎样才能做到这一点?

这实际上是一种非常常见的情况。 你不能做任何基于客户端的事情,因为客户可能会离开并断开连接,你将失去迄今为止所做的工作。 解决方案是使用Service Broker Activation :您在数据库中创建服务并附加激活的过程。 在您的应用程序(或ASP页面)中,您向服务发送消息并为您的过程嵌入必要的参数。 应用程序提交后,该消息将激活服务过程。 服务过程从消息中读取参数并调用您的过程。 由于激活发生在与原始连接无关的服务器线程上,因此这是可靠的。 实际上,服务器甚至可以在执行过程时关闭并重新启动并且工作将被回滚然后恢复,因为激活消息将在重新启动后再次触发服务过程。

更新

我已经发布了如何执行此操作的详细信息,包括我博客上的示例代码: 异步过程执行 。

您可以使用SqlCommandBeginExecuteXXX / EndExecuteXXX方法(取决于它是否返回结果),传递回调委托。

如果你真的想要完全关闭你的应用程序,我建议你在SQL Server Agent中定义一个作业,然后只需执行一个T-SQL语句来手动启动该作业。 语法是:

 sp_start_job { [@job_name =] 'job_name' | [@job_id =] job_id } [ , [@error_flag =] error_flag] [ , [@server_name =] 'server_name'] [ , [@step_name =] 'step_name'] [ , [@output_flag =] output_flag] 

该作业将执行您的存储过程。 您必须有点创意才能传递任何参数。 例如,将参数插入“队列”表并让作业处理队列中的所有行。

队列中的插入触发器也应该起作用,而不是作业。

我建议重新架构。 创建一个“工作队列”表,您可以在其中记录运行存储过程的请求。 然后要么有Windows服务或SQL Server作业不时检查工作队列(或者真的很巧妙并使用触发器)来启动存储过程。 让存储过程不时在工作队列表中更新进度,并且您的前端可以查看告诉用户进度,然后在完成后显示结果。

我更喜欢使用后台服务进行离线处理,用户应用程序告诉服务该做什么,然后断开连接。 该服务可以记录已用时间和错误/状态,并在必要时重新启动。 WCF专为此而设计,并支持与之通信的队列。

让他们关闭应用程序,然后再回来

如果您要允许它们完全关闭应用程序,则必须在不同的ThreadPool中启动单独的.exe或其他内容,以执行调用存储过程的代码。 否则,当您关闭应用程序时,您的线程将会死亡。

您可以执行的另一种方法是允许应用程序在后台运行(可能在通知区域中),然后在作业完成时退出或通知。 您可以使用BeginExecuteNonQuery和EndExecuteNonQuery方法来使用它,以允许它在单独的线程中运行。

您的应用程序的主窗口不需要打开。 如果您将其作为辅助线程启动,只要IsBackground == false ,它就会继续运行。 我通常喜欢通过SQL Server代理或作为客户端 – 服务器应用程序来做这些事情(没有什么能阻止客户端 – 服务器应用程序在同一台机器上运行,甚至是同一个二进制文件)。

有一阵子了…

 using System.Threading; ..... Thread _t = null; void StartProcedure() { _t = new Thread(new ThreadStart(this.StartProc)); _t.IsBackground = false;//If I remember correctly, this is the default value. _t.Start(); } bool ProcedureIsRunning { get { return _t.IsRunning; } //Maybe it's IsActive. Can't remember. } void StartProc(object param) { //your logic here.. could also do this as an anonymous method. Broke it out to keep it simple. }