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

前端之家收集整理的这篇文章主要介绍了delphi – Symbol’Resume’已被弃用/线程错误:句柄无效(6)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个旧的代码,我想升级到Delphi XE.
我有一个关于Resume的编译器警告,我想用Start替换它,但程序崩溃.
  1. constructor THTTPGetThread.Create(aAcceptTypes,aAgent,aURL,aFileName,aUserName,aPassword,aPostQuery,aReferer: String; aBinaryData,aUseCache: Boolean; aProgress: TOnProgressEvent; aToFile: Boolean);
  2. begin
  3. FreeOnTerminate := True;
  4. inherited Create(True);
  5.  
  6. FTAcceptTypes := aAcceptTypes;
  7. FTAgent := aAgent;
  8. FTURL := aURL;
  9. FTFileName := aFileName;
  10. FTUserName := aUserName;
  11. FTPassword := aPassword;
  12. FTPostQuery := aPostQuery;
  13. FTReferer := aReferer;
  14. FTProgress := aProgress;
  15. FTBinaryData := aBinaryData;
  16. FTUseCache := aUseCache;
  17. FTToFile := aToFile;
  18.  
  19. Resume; <------------ works,but I get compiler warning
  20. //Start; <------------ doesn't work
  21. end;

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

解决方法

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

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

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

  1. procedure TThread.AfterConstruction;
  2. begin
  3. if not FCreateSuspended and not FExternalThread then
  4. InternalStart(True);
  5. end;
  6.  
  7. procedure TThread.InternalStart(Force: Boolean);
  8. begin
  9. if (FCreateSuspended or Force) and not FFinished and not FExternalThread then
  10. begin
  11. FSuspended := False;
  12. FCreateSuspended := False;
  13. if ResumeThread(FHandle) <> 1 then
  14. raise EThread.Create(SThreadStartError);
  15. end
  16. else
  17. raise EThread.Create(SThreadStartError);
  18. end;
  19.  
  20. procedure TThread.Start;
  21. begin
  22. InternalStart(False);
  23. end;

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

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

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

猜你在找的Delphi相关文章