在表格中我有一个按钮,“Abort”。在它上面我添加了mythread.terminate
来杀死一个帖子。现在在execute方法中,我使用变量terminated
并对其进行管理。但是,当我没有一个循环,但是一条指令花了很多时间,因为我可以杀死线程?
例如,代码是:
procedure MyThread.Execute;
begin
Sleep (10000);
end;
我想在完成工作之前杀死线程,就像我一样?使用:
MyThread.Terminate
应用程序冻结。
使用while not terminate
,可以使此解决方案有效,从某种意义上说它起作用:
flag := false;
while not terminated do
begin
if not flag then
begin
xxx := myfunction ();
flag := true;
terminate;
end;
end
我试图这样做,我只是觉得它运作良好:
procedure MyThread.Execute;
begin
FreeOnTerminate := True;
while not Terminated do
begin
Sleep (10000); // Just an example for take long time.
Terminate; // This will set Terminated to True, so it won't iterate next time.
end;
end;
我该怎么办?
答案 0 :(得分:3)
如果您需要花费很长时间的单个方法调用,那么最佳解决方案是在单个方法调用内进行更改以定期检查终止。
强行终止线程会导致资源泄漏,僵局以及无辜婴儿的大规模屠杀。实际上,我并不是100%肯定最后一点的真实性,但我认为你可以理解我想说的 - 不要强行终止线程。
如果您无法访问此长时间运行方法的内部,那么您确实处于绑定状态。我过去一直处于这种情况,并设法通过破坏传递给方法的输入数据来解决问题。例如,在我的例子中,我传递了大量的浮点值。将所有这些浮点值设置为信令NaN证明足以使长时间运行的方法gag并返回。也许你将能够使用类似的方法。
答案 1 :(得分:1)
我,我的代码是这样的:
While not Terminated do
begin
// do some work
Sleep(100);
end;
结果是终止前的延迟要小得多。显然,如果没有工作,它可以继续检查新工作,并继续睡觉。
答案 2 :(得分:1)
如果您没有循环并且有多个方法要执行,您只需测试Terminated属性。
procedure MyThread.Execute;
begin
FirstFunction;
if not Terminated then
SecondFunction;
if not Terminated then
ThirdFunction;
end;
但是如果你只有一个花费很多时间的方法(例如一些连接函数),那么就没有干净的方法来阻止它。如何立即停止线程执行有很脏的方法;即Suspend,但要避免使用它,因为它在新版本的Delphi中已被弃用,并且它打算由调试器使用。还有TerminateThread函数更适合使线程退出 但如果你不知道你的长时间运行方法发生了什么,请不要使用它们! 请考虑您可能冻结某些系统资源或使用它们导致死锁。
答案 3 :(得分:0)
如果您想在执行前等待一段时间,请将sleep(10000)
替换为WaitForSingleObject(someEvent, 10000)
,并为每个周期分配一个终止的变量。当调用terminate时,打开事件,让所有堆栈正常完成而不执行新方法。
答案 4 :(得分:0)
使用
MyThread.Terminate
;应用程序冻结。
这只是终止应用程序的情况,这应该不是问题。只需隐藏主窗体,让线程运行即可。
当然,对于在IDE中运行的应用程序实例,这样做效果不太好,因为点击 Ctrl - F2 与使用TerminateThread
具有相同的缺点其他答案已经发出警告。
但是在正常的应用程序运行期间,没有必要知道具有长期终止的线程。