【问题标题】:How to kill a thread in delphi?delphi如何杀死一个线程?
【发布时间】:2010-10-28 16:10:16
【问题描述】:

在delphi 中,TThread 中的一个方法是终止的。似乎子线程无法通过调用终止或释放来杀死另一个线程。 例如 A(主要形式),B(线程单元),C(另一种形式)。

B 正在向主窗体和 C 发送数据(通过调用 syncronize),我们尝试在 C 中终止 B,而 B 通过调用 B.terminate 执行。但是这个方法不起作用,B仍然在工作,直到它以execute方法结束。

请帮忙。提前谢谢你。

【问题讨论】:

    标签: delphi


    【解决方案1】:

    您必须在线程中检查 Terminate 才能使其正常工作。例如:

    procedure TMyThread.Execute;
    begin
      while not Terminated do begin
        //Here you do a chunk of your work.
        //It's important to have chunks small enough so that "while not Terminated"
        //gets checked often enough.
      end;
      //Here you finalize everything before thread terminates
    end;
    

    有了这个,你可以调用

    MyThread.Terminate;
    

    它会在处理完另一块工作后立即终止。这被称为“优雅的线程终止”,因为线程本身有机会完成任何工作并为终止做准备。

    还有另一种方法,称为“强制终止”。您可以致电:

    TerminateThread(MyThread.Handle);
    

    执行此操作时,Windows 会强制停止线程中的任何活动。这不需要在线程中检查“已终止”,但可能会非常危险,因为您在操作中间杀死了线程。之后您的应用程序可能会崩溃。

    这就是为什么在您完全确定您已经弄清楚所有可能的后果之前,您永远不会使用 TerminateThread。目前还没有,所以使用第一种方法。

    【讨论】:

    • 不仅应用程序可能崩溃,而且tad使用的资源也不会被释放。 TerminateThread() 是一个“极值比率”调用。
    • @himself:当发现 Terminated 设置为 True 时,您可以让线程在线程上下文中调用“Abort”。 “中止”将引发一个静默异常。有时这种方式比有一个大的“while not Terminated”循环更容易实现逻辑。
    • 亲爱的自己:只是测试你的代码,但线程不能正常退出。虽然未终止,但开始直到线程执行功能结束。为什么?相反,Terminatethread 函数做得很好,尽管大多数专家不推荐它。
    • @user482742:编辑您的问题并添加代码,以便我们告诉您问题所在。
    • @himself 我应该在使用列表中写入什么单元以使 TerminateThread 工作?如果那是“Windows”,那么它需要 2 个参数...
    【解决方案2】:

    其实

    关于如何强行终止线程,目前对该问题的投票最多的答案是不正确的(例如 34 名赞成者...)。

    不要使用ThreadId 作为TerminateThread 过程的参数。使用ThreadId 很可能会导致“无效句柄”错误,或者在更糟糕的情况下会导致另一个线程终止。

    您应该将thread handle 作为参数传递:

    TerminateThread(MyThread.Handle);
    

    有关线程句柄和 id 之间差异的更多信息可以找到here

    编辑

    似乎@himself 在看到我的回答后纠正了他的错误,所以这不再相关。

    【讨论】:

    • @kobik 是的,我过去也是这样做的,但看看这个社区是如何运作的:很多人在没有实际检查自己的答案是否正确的情况下就 +1。
    【解决方案3】:

    Terminate 不会杀死线程;它设置Terminated 属性以通知线程它需要终止。观察Terminated 并优雅地关闭自己是线程的责任。

    【讨论】:

      【解决方案4】:

      Terminate 方法所做的只是将Terminated 属性设置为 true。所以你必须手动继续检查该属性,然后当它设置为 true 时退出线程方法。

      【讨论】:

        【解决方案5】:

        如果您可能想终止一个线程,那么您最好生成另一个应用程序并在您认为它失败时将其杀死 - 然后窗口会在您之后整理。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-06-28
          • 1970-01-01
          • 2022-11-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多