我仍然是线程新手。我想创建一个程序,在主线程创建必要的表单时测试有效的Internet连接。代码片段在构造函数的末尾停止,并显示“无法在正在运行或挂起的线程上调用Start”错误。由于某种原因,主要形式在此错误后关闭
constructor TPingThread.Create(IDThread: Integer);
begin
Self.FID:=IDThread;
Self.FreeOnTerminate:=true;
end;
destructor TPingThread.Destroy;
begin
EndThread(FID);
inherited;
end;
procedure TPingThread.Execute;
var
iTimeOuts, K: Byte;
sWebpage: String;
begin
inherited;
iTimeOuts:=0;
FIdPing:=TIdHTTP.Create(nil);
for k:=1 to 3 do
begin
Try
FIdPing.ConnectTimeout:=2000;
sWebpage:=FIdPing.Get('http://www.google.co.za')
Except
On Exception do inc(iTimeOuts);
End;
end;
if iTimeOuts=3 then MessageDlg('A working internetconnection is needed to reset your password',mtWarning,[mbOK],0);
if iTimeOuts=0 then FInternetConnection:=false
else FInternetConnection:=true;
FreeAndNil(FIdPing);
end;
答案 0 :(得分:4)
您的代码存在一些问题:
您需要调用inherited
构造函数:
constructor TPingThread.Create(IDThread: Integer);
begin
inherited Create(false); // Or true to create a suspended thread
Self.FID:=IDThread;
...
删除inherited
方法中的Execute
调用,因为这是TThread
的抽象声明。这本身并不是错误,但为了清楚起见应该避免。
在执行方法中创建FIdPing
后使用try / finally。
正如@mjn所说,无需拨打EndThread()
,因为TThread
会为您处理此问题。
从线程调用VCL MessageDlg()
不是线程安全的。您需要同步调用或使用Application.MessageBox
,一个Delphi包装器到Windows MessageBox
。最好的解决方案是跳过对话框并将错误消息传递给主线程,无论如何都需要知道此错误。