【问题标题】:Terminating a thread in Delphi 10 with Android使用 Android 终止 Delphi 10 中的线程
【发布时间】:2017-12-14 19:17:20
【问题描述】:

我正在使用如下所示的基本设置创建一个线程。显然一切正常,但是当我运行MyThread.Terminate 时,我注意到Destroy 没有运行。 Destroy 仅在关闭主应用程序时执行。

结束线程的正确方法是什么?

基本线程

// MyThread "TPoolingThread"
constructor TPoolingThread.Create;
begin
   inherited Create(True);

   // Initializing something
end;

destructor TPoolingThread.Destroy;
begin
   inherited Destroy;
end;

procedure TPoolingThread.Execute;
begin
   try
      while (not Terminated) do begin
         sleep(100);
         // do something
      end;
   finally
      if not Terminated then
         Terminate;
   end;
end;

执行线程

// Main Application 

   //////////////////////////////////////////
   // Create and Start
   MyThread := TPoolingThread.Create;

   if Assigned(MyThread.FatalException) then
      raise MyThread.FatalException;

   MyThread.Start;

   //////////////////////////////////////////
   // Stop
   MyThread.Terminate;

【问题讨论】:

  • Delphi 在 Android 上使用 ARC 进行对象生命周期管理。在清除所有对线程对象的引用之前,不会调用析构函数。调用Terminate 后,您是否正在清除MyThread 指针?此外,FatalException 仅在未捕获的异常从 Execute 逃逸时才设置,因此它永远不会在您显示的代码中设置。您可以在 OnTerminate 事件中检查它。如果Create 失败,它将引发一个未存储在FatalException 中的异常
  • 不,我没有在调用 Terminate 后清除 MyThread 指针。我的基本代码仅此而已。我应该做 MyThread = nil 吗?关于FatalException,好的。我会做的。谢谢!
  • 你的编辑把事情弄得一团糟。你不会从它的 Execute 方法中终止或线程。
  • @DalijaPrasnikar,我遵循了 Embarcadero 的一个示例,他们使用 try except 我使用了 try finallyfinally 错了吗?我只是想让线程优雅地结束,而仅通过使用调试,我就无法理解最正确的方法。 Embarcadero 示例是:docwiki.embarcadero.com/RADStudio/Tokyo/en/…。感谢您的帮助。
  • 如何终止线程 - 使用 Terminate 方法(线程外的 Execute 方法)。为什么在终止时不调用 Destroy - 因为它与终止线程无关。其余的变成了调试会话,我无法帮助您,因为问题出在您看不到的其他代码中。我建议您再次编辑此问题 - 为您面临的问题制作完整且最小的示例,也许有人会回答。

标签: android multithreading delphi


【解决方案1】:

我想通过定义'结束一个线程'来作为我的答案的序言。我将假设 '结束一个线程' 您的意思是在 TPoolingThread.Execute 过程中停止循环。

终止线程

您用来终止线程的方法是完全可以接受的。现在至于为什么,请允许我告诉你this snippet

版本 1

在 Try-Finally 构造中,无论 try 子句中发生什么,都保证绝对执行 finally 语句。然而,Finally 子句实际上并不处理任何异常——如果没有找到 except 子句,程序将终止(见下面的注释)。

因此,如果您的循环中的代码抛出异常,您将告诉您的 TPoolingThread 对象它已被终止。

为什么不调用destroy

正如Remy Lebeau and Dalija Prasnikar 建议的那样。 Terminate 不应该调用destroy:

System.Classes.TThread.Terminate:

通过将 Terminated 属性设置为 true 来指示线程终止。 Terminate 将线程的 Terminated 属性设置为 true,表示应尽快终止线程。

为了使 Terminate 工作,线程的 Execute 方法和 Execute 调用的任何方法都应该定期检查 Terminated 并在它为真时退出。

如果您想了解有关 Delphi 中用于 Android 开发的 ARC 的更多信息,我会留给您this link

【讨论】:

  • 抱歉,try...finallyExecute 方法中的 finally 块仅包含检查 Terminated 和调用 Terminate 是完全没用的。如果引发异常,线程将被终止——无论如何它都会退出Execute 方法。线程内未处理的异常也会导致应用程序崩溃。
猜你喜欢
  • 2011-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-10
相关资源
最近更新 更多