我想基于后台线程实现可中断的任务。实现TTask.Stop
方法的最简洁方法是什么?如何中止后台线程?
在线程上下文中执行的代码使用匿名方法传递给任务,并且可以包含阻塞调用,因此我不能依赖于在代码中定期检查Terminated
标志的事实
感谢您的任何意见。
使用D2010以防万一(TThread
中的某些内容似乎已发生变化)
答案 0 :(得分:7)
无法安全地中止正在运行的线程。无论是否使用Delphi编写,以及是否使用Delphi 2010或更早版本,Windows程序都是如此。这是一个操作系统限制,如果你想调用它,但实际上它是线程的限制,因为中止线程而不确定它没有持有锁或类似的东西会对你的程序造成严重破坏。
您可以做的是调用TerminateThread()
API函数,即 evil 。阅读此链接中的问题和警告列表,看看您是否仍想调用它。没有任务代码的合作,没有其他方法可行。
答案 1 :(得分:7)
将作业隔离到单独的进程中。根据您与后台工作的沟通方式,这可能是保证您可以彻底中止的最佳方式。
例如,使用共享内存进行通信可能不是一个好的理念;使用文件或管道,或类似的机制,当另一端被杀死时不会破坏或停止。如果使用命名互斥锁进行跨进程同步,请注意这些同步原语存在特定的错误状态:如果最后持有该原语的线程(或隐式地,进程的主线程)是WaitForSingleObject和friends,则返回WAIT_ABANDONED没有干净地释放它就终止了。基本上,这意味着您需要使用分阶段事务方法进行数据传输,以便您可以忽略在终止时被修改的可能不一致的状态。