2008-10-31 63 views
5

我有Delphi的线程问题。我想这在其他语言中也很常见。我有一个很长的过程,我在一个线程中完成,它填充主窗口中的列表。但如果某些参数在同一时间内发生变化,那么我应该停止当前正在执行的线程并从头开始。 Delphi建议通过设置Terminated:= true并在线程中检查此变量的值来终止线程。然而,我的问题是,长的执行部分被埋在一个库调用中,在这个调用中,我无法检查Terminated变量。因此我不得不等待这个库调用完成,这影响了整个程序。如何优雅地停止长执行线程?

在这种情况下,首选的方法是什么?我可以立即杀死线程吗?

+1

什么是长期运行的库调用? – 2008-11-01 03:41:11

回答

3

线程需要合作才能实现正常关机。我不确定Delphi是否提供了一种机制来中止另一个线程,但是这样的机制可以在.NET和Java中使用,但是应该被认为是最后的选择,并且应用程序的状态在使用之后是不确定的。

如果你可以在任意点杀死一个线程,那么你可以在内存分配器(例如)中持有一个锁时终止它。当您的主线程下一个需要访问该锁时,这会使程序处于悬挂状态。

9

首选的方法是修改代码,使其不会阻止未检查取消。

由于您无法修改代码,因此您无法做到这一点;你或者不得不忍受后台操作(但你可以将其与任何UI分离,以使其完成将被忽略);或者,您可以尝试终止它(TerminateThread API将粗暴地终止给定其句柄的任何线程)。尽管终止并不干净,但像Rob说的那样,线程所持有的任何锁都将被放弃,并且受此类锁保护的任何交叉线程状态可能处于损坏状态。

你可以考虑在单独的可执行文件中调用函数吗?也许使用RPC(管道,TCP,而不是共享内存,由于相同的锁问题),以便您可以终止进程而不是终止线程?过程隔离会给你提供更多的保护。只要你不依赖跨进程命名像互斥体这样的东西,它应该比杀死线程更安全。

+0

这听起来是一个很好的建议。在另一个进程中进行此调用将在放弃它之后留下任何痕迹。 – Glenner003 2008-11-03 09:53:25

3

如果您不能修改代码来检查终止,那么只需将其优先级设置得非常低,并且在返回时忽略它。

0

我在回信中写道这一个similar question

我使用基于异常的技术 多数民众赞成工作得很好,我在 数量的Win32应用程序。

要终止线程,我使用 QueueUserAPC排队调用 函数,该函数抛出异常。 但是,引发的异常 不是从类型 “Exception”派生的,因此我的线程的包装过程只会被 捕获。

我已经非常成功地使用了C++ Builder应用程序。我没有意识到Delphi与C++异常处理的所有细微之处,但我期望它可以很容易地被修改为工作。