我也碰到这个问题,给你一段代码 在TCPServer.Active := false前 加一个函数 procedure TfrmIndy.btnDisconnectAll; var List: TList; I: Integer; begin List := TCPServer.Threads.LockList; try for I := 0 to List.Count - 1 do begin try //if TCPServer.Checked then //begin //TIdPeerThread(List.Items[I]).Connection.WriteLn('#'); //end; TIdPeerThread(List.Items[I]).Connection.Disconnect; except //on E: EIdNotConnected do //begin // //Dont worry about this error //end; on E: Exception do begin form1.spSkinMemo1.Lines.Add('Exception (' +datetimetostr(Now) + ') [' + E.ClassName + ']: ' + E.Message); form1.spSkinMemo1.Lines.Add('The thread has been stopped'); TIdPeerThread(List.Items[I]).Stop; end; //on end; //try end; //for finally TCPServer.Threads.UnlockList; end; end;在直接运行EXE时不会报错,但在程序运行时还是会保超时的错。
procedure Tfrm_ServerMain.BitBtn2Click(Sender: TObject); //强制关闭所有连接线程 var i,j : integer; begin j := MyList.LockList.Count; MyList.UnlockList; if j > 0 then begin for i := 0 to j -1 do begin TIdPeerThread(MyList.LockList.Items[i]).Connection.Disconnect; MyList.UnlockList; end; end; end;
tyxycylwxl(自由生活):我用的是TIdTCPServer组件,代码如下: 。 。 VarTList:=Form1.IdTCPS.Threads.LockList; For Place:=0 To VarTList.Count Do Begin TIdPeerThread(VarTList).Connection.Disconnect; Try TIdPeerThread(VarTList).WaitFor; Except End; End; If Form1.IdTCPS.Active Then Form1.IdTCPS.Active:=False; 。 。 。 却出这样的错误:Access violation at address BE66C38B. Read of address BE66C38B
VarTList:=Form1.IdTCPS.Threads.LockList; For Place:=0 To VarTList.Count Do Begin Try TIdPeerThread(VarTList.Items[Place]).FreeOnTerminate:=True; TIdPeerThread(VarTList.Items[Place]).Connection.Disconnect; TIdPeerThread(VarTList.Items[Place]).WaitFor; Except On WaitforError:Exception Do Begin Form1.Memo1.Lines.Add(WaitForError.Message); End; End; End;改成这样,窗体就没了反映。 整个程序在cpu中也没有看到占多大的cpu时间。
我的程序已经完全改成了ics控件来代替indy控件,现在一切正常,唯一的一个特点,就是用leapftp,flashfxp上传或者下载时程序界面反应迟钝,可能涉及到数据发送创建线程的问题,正在焦头烂额! 至于你说的错误: Access violation at address BE66C38B. Read of address BE66C38B 有可能是访问了你的不存在的线程列表出现的错误:提供例子代码如下:procedure TfrmMain.StopServices(); var e,h:integer; endthr:TIdPeerThread; begin e:=thrList.Count; if e>0 then begin for h:=0 to e-1 do begin endthr:=thrList.Items[h]; endthr.FreeOnTerminate:=true; endthr.Connection.Disconnect; try endthr.WaitFor; except end; end; end; end;
try
sCommand:=idTCPClient1.ReadLn();
except
Exit;
end;改了之后调试时(即用Delphi上的运行时)还会有错,直接执行编译的exe就不再提示出错了.
在TCPServer.Active := false前
加一个函数
procedure TfrmIndy.btnDisconnectAll;
var
List: TList;
I: Integer;
begin
List := TCPServer.Threads.LockList;
try
for I := 0 to List.Count - 1 do
begin
try
//if TCPServer.Checked then
//begin
//TIdPeerThread(List.Items[I]).Connection.WriteLn('#');
//end;
TIdPeerThread(List.Items[I]).Connection.Disconnect;
except
//on E: EIdNotConnected do
//begin
// //Dont worry about this error
//end;
on E: Exception do
begin
form1.spSkinMemo1.Lines.Add('Exception (' +datetimetostr(Now) + ') [' + E.ClassName + ']: ' + E.Message);
form1.spSkinMemo1.Lines.Add('The thread has been stopped');
TIdPeerThread(List.Items[I]).Stop;
end; //on
end; //try
end; //for
finally
TCPServer.Threads.UnlockList;
end;
end;在直接运行EXE时不会报错,但在程序运行时还是会保超时的错。
你要的话,我这有程序
bloodsucker_1◎163.com
哪位高手指点一下
var
i,j : integer;
begin
j := MyList.LockList.Count;
MyList.UnlockList;
if j > 0 then
begin
for i := 0 to j -1 do
begin
TIdPeerThread(MyList.LockList.Items[i]).Connection.Disconnect;
MyList.UnlockList;
end;
end;
end;
获得线程的id后如下操作线程:
Athread.FreeOnterminated:=true(可以不要,因为indy在完成一个客户连接后,自动销毁线程)
Athread.connection.disconnect;(调用此事件,实际上就是告诉客户,将结束这个线程,indy会自动销毁)
try
Athread.WaitFor
except
end;(不如此,程序会报“句柄无效”的错误,因为此时indy可能已经结束了线程)(如果你要终止很多用户,创建一个线程列表,然后循环,在循环中加入上述得处理方法,便一切ok,我就时这样处理得,欢迎使用我得实验品:E-Serv软件,发布在“上传下载的栏目里”,你也可以来信索取:[email protected] .你可以看:我的软件就可以在有客户端连接的时候强行终止客户的连接)//此时就可以终止服务器了
idTcpServer.Active:=false(调试时当然有异常,保护起来,脱离调试环境,运行程序,一切ok)
愿能帮得上你得忙◎!
。
。
VarTList:=Form1.IdTCPS.Threads.LockList;
For Place:=0 To VarTList.Count Do Begin
TIdPeerThread(VarTList).Connection.Disconnect;
Try
TIdPeerThread(VarTList).WaitFor;
Except
End;
End;
If Form1.IdTCPS.Active Then Form1.IdTCPS.Active:=False;
。
。
。
却出这样的错误:Access violation at address BE66C38B. Read of address BE66C38B
For Place:=0 To VarTList.Count Do Begin
Try
TIdPeerThread(VarTList.Items[Place]).FreeOnTerminate:=True;
TIdPeerThread(VarTList.Items[Place]).Connection.Disconnect;
TIdPeerThread(VarTList.Items[Place]).WaitFor;
Except
On WaitforError:Exception Do Begin
Form1.Memo1.Lines.Add(WaitForError.Message);
End;
End;
End;改成这样,窗体就没了反映。
整个程序在cpu中也没有看到占多大的cpu时间。
至于你说的错误:
Access violation at address BE66C38B. Read of address BE66C38B
有可能是访问了你的不存在的线程列表出现的错误:提供例子代码如下:procedure TfrmMain.StopServices();
var e,h:integer;
endthr:TIdPeerThread;
begin
e:=thrList.Count;
if e>0 then begin
for h:=0 to e-1 do begin
endthr:=thrList.Items[h];
endthr.FreeOnTerminate:=true;
endthr.Connection.Disconnect;
try
endthr.WaitFor;
except
end;
end;
end;
end;