In article <3e411...@newsgroups.borland.com>, na@not_an_address.com
says...
Quote
> James, Martin - thank you both very much, that clears a lot up. Looks like
> I'll have some redesigning to do, but it sounds as though the separate
> thread route is really the way to go.
> Appreciate your time - best regards
Hi, James. Seems that I am having the same problem as you. I have a FTP
Client APP built with Indy in Delphi 5 which occasionally hangs with no
exception, blocking the main thread appearently doing nothing.
By now I have abandoned the attempt to solve the problem, as I haven't
catched the cause yet :-( so I am trying to work aroudnd it, basically
to disconnect and reconnect in case of a hang.
I hope you'll be patient enough to read this (I hope in anyone else too!
:-] )
I tried to use IdAntiFreeze and a TTimer to catch the error forcing an
exception by ABORting. This is a snippet:
-----------------------------------------------------------------------
1. A smart routine that gets a file
-----------------------------------------------------------------------
function TMainFrm.SafeGet (asRemSrc, asLocDst : string) : boolean;
var
lbDone, lbGood : boolean;
liTries : integer;
begin
lbDone := false; lbGood := false; liTries := 0;
FailTimer.Enabled := true;
while (not lbDone) do begin
try
MyFTP.Get(asRemSrc,asLocDst,true,false);
lbDone := true; lbGood := true;
except
on E:Exception do begin
Inc(liTries);
if (liTries>=5) then begin
lbDone := true;
lbGood := false;
end;
end;
end;
end;
FailTimer.Enabled := false;
Result := lbGood;
end;
-----------------------------------------------------------------------
Before a loop I enable a timer to catch a timeout. the presence of a
TIdAntiFreeze component seems to allow the Timer to run.
I simpilfied the operation, as the exception could be triggered other
than my Abort method, anyway we can suppose by now that the Abort method
is the only reason for the exception to fire at this moment.
Now let's examine the FailTimer event, which is triggered any second
(the Timer has an interval of 1000):
-----------------------------------------------------------------------
2. FailTimer event
-----------------------------------------------------------------------
procedure TMainFrm.FailTimerTimer(Sender: TObject);
begin
// first of all avoid loops
FailTimer.Enabled := false;
Inc(iiIdleTime);
// more than 20 seconds of inactivity...
if (iiIdleTime>=20) and (MyFTP.Connected) then begin
Inc(iiTotalFail);
if (iiTotalFail>10) then begin
ibStopped := true;
end
else begin
MyFTP.Abort;
MyFTP.Quit;
MyFTP.Connect;
if (isCurDir<>'') then MyFTP.ChangeDir(isCurDir);
end;
end;
FailTimer.Enabled := true;
end;
-----------------------------------------------------------------------
When 20 seconds pass without ANY FTP action, I assume there is a{*word*154}
command. I set the buffer sizes to 256 bytes, and on any activity I
reset the iiIdleTime to zero, it means on OnStatus, OnWork, OnWorkBegin,
OnWorkEnd events.
This seems not to work, as it seems that not in all the cases the Abort
method raises an exception.
A) Could this be related to the fact that I do not wait any time between
the MyFTP.Abort and the MyFTP.Connect?
B) Have you then solved this using threads? If so, please, can you give
me a hint on the implementation? I am not very fond on threads dealing
with FTP.
I appreciate your time too, believe me!
Best regards
----------------------------------------
Ing. Piero Salandin
piero.salan...@eriador.it
icq#139345810
----------------------------------------