delphi – 线程错误:当尝试释放挂起的线程时,句柄无效(6)

delphi – 线程错误:当尝试释放挂起的线程时,句柄无效(6),第1张

概述在给定的示例中,我在调用AThread.Free时收到异常. program Project44;{$APPTYPE CONSOLE}uses SysUtils, Classes, Windows;type TMyException = class(Exception);var AThread: TThread;begin AThread := TThread.C 在给定的示例中,我在调用AThread.Free时收到异常.
program Project44;{$APPTYPE CONSolE}uses  SysUtils,Classes,windows;type  TMyException = class(Exception);var  AThread: TThread;begin  AThread := TThread.Create(True);  try    AThread.FreeOnTerminate := True;    //I want to do some things here before starting the thread    //During the setup phase some exception might occur,this exception is for simulating purpouses      raise TMyException.Create('exception');  except    AThread.Free; //Another exception here  end;end.

我有两个问题:

>在给定的示例中,如何释放AThread的TThread实例?
>我不明白,为什么TThread.Destroy在销毁之前调用Resume.这有什么意义?

解决方法 您不能将FreeOnTerminate设置为True并在线程实例上调用Free.你必须做一个或另一个,但不是两个.因为它代表你的代码破坏线程两次.你必须永远不要销毁一个对象两次,当然,当析构函数第二次运行时,会发生错误.

这里发生的事情是,由于您创建了线程暂停,因此在您明确释放线程之前不会发生任何事情.当你这样做时,析构函数恢复线程,等待它完成.然后,这会导致Free被再次调用,因为您将FreeOnTerminate设置为True.第二次调用Free会关闭句柄.然后返回到线程proc并调用ExitThread.这会失败,因为线程的句柄已经关闭.

正如Martin在评论中指出的那样,你不能直接创建TThread,因为TThread.Execute方法是抽象的.此外,您不应使用已弃用的Resume.使用“开始”开始执行挂起的线程.

我个人不喜欢使用FreeOnTerminate.使用此功能会导致线程在创建它的其他线程上被销毁.当您想要忘记实例引用时,通常会使用它.这使您不确定在进程终止时线程是否已被销毁,或者在进程终止期间是否终止并释放自身.

如果你必须使用FreeOnTerminate,那么你需要确保在将FreeOnTerminate设置为True后不要调用Free.因此,显而易见的解决方案是在调用Start之后立即将FreeOnTerminate设置为True,然后忘记线程实例.如果在准备好开始之前有任何例外,那么你可以放心地释放线程,因为FreeOnTerminate在那时仍然是False.

Thread := TMyThread.Create(True);Try  //initialise thread objectExcept  Thread.Free;  raise;End;Thread.FreeOnTerminate := True;Thread.Start;Thread := nil;

更优雅的方法是将所有初始化移动到TMyThread构造函数中.然后代码看起来像这样:

Thread := TMyThread.Create(True);Thread.FreeOnTerminate := True;Thread.Start;Thread := nil;
总结

以上是内存溢出为你收集整理的delphi – 线程错误:当尝试释放挂起的线程时,句柄无效(6)全部内容,希望文章能够帮你解决delphi – 线程错误:当尝试释放挂起的线程时,句柄无效(6)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1279324.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-09
下一篇 2022-06-09

发表评论

登录后才能评论

评论列表(0条)

保存