delphi – Symbol’Resume’已被弃用/线程错误:句柄无效(6)

前端之家收集整理的这篇文章主要介绍了delphi – Symbol’Resume’已被弃用/线程错误:句柄无效(6)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个旧的代码,我想升级到Delphi XE.
我有一个关于Resume的编译器警告,我想用Start替换它,但程序崩溃.
constructor THTTPGetThread.Create(aAcceptTypes,aAgent,aURL,aFileName,aUserName,aPassword,aPostQuery,aReferer: String; aBinaryData,aUseCache: Boolean; aProgress: TOnProgressEvent; aToFile: Boolean);
begin
  FreeOnTerminate := True;
  inherited Create(True);

  FTAcceptTypes := aAcceptTypes;
  FTAgent       := aAgent;
  FTURL         := aURL;
  FTFileName    := aFileName;
  FTUserName    := aUserName;
  FTPassword    := aPassword;
  FTPostQuery   := aPostQuery;
  FTReferer     := aReferer;
  FTProgress    := aProgress;
  FTBinaryData  := aBinaryData;
  FTUseCache    := aUseCache;
  FTToFile      := aToFile;

  Resume;      <------------ works,but I get compiler warning
  //Start;     <------------ doesn't work
end;

当我使用START时我得到的错误是:“线程错误:句柄无效(6)”.
我不想复杂的东西(冻结/同步线程).我只想从互联网上下载一个文件,而不会阻止GUI.

解决方法

简单的答案是,您不应该创建此线程已暂停,因为您希望它立即启动.删除对Start的调用,并将False传递给继承的构造函数.

请注意,直到所有构造函数都运行到完成为止,线程才会启动,因此其意义与您发布的代码相同.

至于为什么您的代码失败,请查看源代码中的以下摘录:

procedure TThread.AfterConstruction;
begin
  if not FCreateSuspended and not FExternalThread then
    InternalStart(True);
end;

procedure TThread.InternalStart(Force: Boolean);
begin
  if (FCreateSuspended or Force) and not FFinished and not FExternalThread then
  begin
    FSuspended := False;
    FCreateSuspended := False;
    if ResumeThread(FHandle) <> 1 then
      raise EThread.Create(SThreadStartError);
  end
  else
    raise EThread.Create(SThreadStartError);
end;

procedure TThread.Start;
begin
  InternalStart(False);
end;

您的代码使用CreateSuspended = True调用继承的构造函数.这将FCreateSuspended设置为True.然后在TThread.AfterConstruction运行之前调用Start.这成功地启动了线程,但是至关重要的是将FCreateSuspended置于False.然后当TThread.AfterConstruction它尝试恢复线程失败,因为它已经在运行.

我认为Delphi代码很好,因为从构造函数调用Start是不正确的.您需要确保所有构造函数都已运行,并且派生类构造函数调用Start之后运行.你没有任何派生类,但这不是要点 – 不支持从构造函数调用开始.

最重要的是你应该创建这个线程不被挂起,并且允许你从AfterConstruction代表你调用Start.

猜你在找的Delphi相关文章