终止长时间运行的SQL命令

3

假设我们的前端应用程序(C#)与 SQL Server 建立一系列连接并执行一系列存储过程,可能需要几个小时才能完成。我需要有一个功能来“取消”正在运行的存储过程。我知道可以通过Sqlcommand.Cancel()来实现,但这似乎并不总是有效。有更好的方法来实现吗?


如果你知道进程 ID,你可以通过网络发送 kill 命令。如果你不知道进程 ID,可以使用 sp_who 命令找到它。 - gh9
1
也许这个答案会给你一些提示。这仅适用于应用程序端的连接终止。它不会真正杀死在Sql服务器实例上阻塞执行的资源。 - vendettamit
@Stepup 谢谢,但 CommandTimeout 对我来说不是一个选项,因为有些存储过程预计需要那么长时间。如果必要的话,我需要一种正确的方法来取消它们。 - Time Machine
1
考虑使用异步方法?例如:https://msdn.microsoft.com/zh-cn/library/7b6f9k7k(v=vs.110).aspx - Dan Field
@gh9 我需要从前端完成这个任务,理想情况下,用户可以取消自己的长时间运行的 SQL 命令... - Time Machine
显示剩余6条评论
2个回答

2
如果取消不起作用,杀死进程也不会有用。它们必须使用相同的机制。在内部为它们使用不同的机制没有意义。
“我希望从前端完成此操作,理想情况下用户将取消自己的长时间运行的SQL命令。”
模拟向用户展示操作已被取消,但实际上操作仍在后台完成是一种常见的技术。在.NET中,有许多操作无法立即取消。在这种情况下,最好的选择是隔离该操作并让其在后台完成。
TPL使这个过程变得相当容易。您可以搜索“.net cancel task”或“.net cancel uncancellable task”来获取一些提示。再次强调,只需继续执行并仅请求取消,而不需要等待。
您不需要使用async/await或async SqlCommand方法来使其工作,但您可以这样做。只是提到这一点,因为这是一个常见的误解。

-2

你可以将获取大数据的所有代码放在线程中,

并计时或为用户提供一个取消数据采集的按钮,

如果经过一定的时间或用户按下取消按钮,进程将被取消。

1)声明一个全局变量

Thread tr;

然后当线程启动时,启动一个计时器,当计时器上设置的时间已经过去时,它将调用elapsed...方法,我不记得确切的名称了。搜索如何在C#上使用计时器的过程,然后在这个Elapsed方法中添加这一行。

tr.Abort(); //Aborting the thread of course this will cancel all the code inside the thread executed method.

如果你不想使用计时器,可以添加一个按钮,然后在其单击事件处理程序方法中添加相同的行:
tr.Abort();

这将取消线程方法中执行的代码。


谢谢Bilal,但不确定使用Abort()方法是否是终止过程的最安全方式? - Time Machine
Abort不会终止SQL Server端的任何操作。此外,谷歌搜索“thread.abort evil”可了解它永远不能用于取消操作。 - usr
"usr 说得对。Thread.Abort 通常也不像大多数开发者认为的那样起作用。请参考文档以了解其内部工作原理。" - Alex Maker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接