如何停止ThreadPool中的线程?
我开始一个长操作(通常是对数据库的长查询(SELECT))。 这可能需要很长时间,我想添加功能来停止此操作。 代码如下:
ThreadPool.QueueUserWorkItem(a => action.DoLongAction());
public void DoLongAction()
{
var sql = Tables.Where(el => el.Some == "XXX"); // dynamically constructed LINQ query to database
var result = db.Query(sql);
}
我无法使用标志信号来停止该线程。因为,长操作不在我的代码中,而是在数据库进程中(sql查询大约5分钟)。
我怎样才能正确地停止这个线程?
UPD1。不是普通的 SQL,而是 LINQ(EF4、BLToolkit)
I start a long operation (usually long query (SELECT) to database).
It might take long time, and I want to add capability to stop this action.
Code looks like:
ThreadPool.QueueUserWorkItem(a => action.DoLongAction());
public void DoLongAction()
{
var sql = Tables.Where(el => el.Some == "XXX"); // dynamically constructed LINQ query to database
var result = db.Query(sql);
}
I can't use signals of flags, to stop this thread. Because, long operation isn't in my code, but in database process (sql query about 5 mins).
How can I stop this thread correctly?
UPD1. Not plain SQL, but LINQ (EF4, BLToolkit)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
考虑使用 BackgroundWorker 类。支持取消。
但是,只有在数据库提供程序支持取消查询的情况下,您才能以安全的方式取消查询。您的代码看起来不支持取消。
更新:经过一番讨论,以下信息也值得放入答案中:
正如 Guillaume 指出的那样,SqlCommand 支持取消,但所使用的数据库驱动程序也需要支持它。所以最好的方法是:
将 SqlCommand 或从它派生的类用于您的 DBMS,执行查询并尝试取消它并查看它是否受支持。如果不支持,您将收到异常。
如果支持,SqlCommand.Cancel 的示例将帮助您实现您想要的行为。
Consider using the BackgroundWorker class. It supports canceling.
But you can only cancel the query in a safe manner, if the database provider supports canceling it. Your code doesn't look like it supports canceling.
Update: After some discussion, the following info also is worth to be put into the answer:
SqlCommand supports cancellation as Guillaume points out, but the database driver used needs to also support it. So best way to do it:
Use SqlCommand or the class derived from it for your DBMS, execute the query and try to cancel it and see whether it is supported. If it is not supported, you will get an exception.
If it is supported, the example for SqlCommand.Cancel will help you to implement the behavior you want.
如果您想取消 SQL 命令,请查看 SqlCommand.Cancel 文档。
If you want to Cancel a SQL command, have a look at SqlCommand.Cancel documentation.
如果您确实需要手动中止此线程,那么您可以使用 线程类。
有关如何使用它的详细信息,您可以查看此在线资源。
请注意,通常,使用 Thread.Abort(); 并不是最佳实践,除非您要结束程序并想要终止所有正在运行的线程。
在您的情况下,当您尝试结束 SQL 查询时,您应该寻找其他方法来停止它(SqlCommand.Cancel(), ISession.CancelQuery(), ...)
If you really need to abort this Thread manually, then you can use the Thread class.
For details about how to use it, you can look at this online resource.
Please note that usually, using
Thread.Abort();
is not a best practice, except when you are ending your program and wants to terminate all the running threads.In your case, as you are trying to end a SQL query, you should look at other ways to stop it (SqlCommand.Cancel(), ISession.CancelQuery(), ...)
您还可以为 SQLCommand 添加超时值。也就是说,如果未完成,则在 x 秒后取消。
You can also add a timeout value for the SQLCommand. aka, cancel after x seconds if not finished.