我有一个旧的代码,我想升级到Delphi XE.
我有一个关于Resume的编译器警告,我想用Start替换它,但程序崩溃.
我有一个关于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.