tidFtp inside thread do not abort

Giganews Newsgroups
Subject: tidFtp inside thread do not abort
Posted by:  Mauricio (mauric…@uaisol.com.br)
Date: Wed, 3 Dec 2003

Hi guys, I have a thread that refreshes a jpg image on a ftp server using
TidFtp (I use that in a webcam program). The program creates several
instances of this thread each are responsable for a couple of webcams (the
program cam manage several webcams at a time), so there are several
connection to the ftp server. The problem that I'm having is the following:

Sometimes the threads need to be finalized and restarted (like when a user
change the ftp configurations). So the program needs to wait all thread
finished and create all again. I make that using a Counter. When a thread is
created the Counter is incremented, and the counter is decremented on the
OnTerminate event of each thread. The program uses

            //(..) Call Finalize for all runnig threads.
            While FtpThreadsCount>0 do Application.ProcessMessages;

to wait all thread finish without hangs the application. And then start all
the threads again.
I will put some code here to explain how the things are working now:

The Thread.Create code has that
(..)
  Ftp:=tidFtp.Create(nil);
  ftp.OnWork:=Self.FTPWork;
  ftp.OnWorkBegin:=Self.FTPWorkBegin;
  ftp.OnWorkEnd:=Self.FTPWorkEnd;
(..)
so I can manage some events inside the thread

The finalize method of the thread has:

    Self.Terminate;
    AbortTransfer:=Transferring;

That set Teminated to True and see if we need to abort a transfer in
progress.

The Ftp events have:

procedure ThreadFTP.FTPWork(Sender: TObject; AWorkMode: TWorkMode;
  const AWorkCount: Integer);
begin

If AbortTransfer then
        Ftp.Abort;

end;

procedure ThreadFTP.FTPWorkBegin(Sender: TObject;
  AWorkMode: TWorkMode; const AWorkCountMax: Integer);
begin
AbortTransfer:=false;
Transferring:=true;
end;

procedure ThreadFTP.FTPWorkEnd(Sender: TObject; AWorkMode: TWorkMode);
begin
Transferring:=false;
end;

The main code of the Execute method is:

              (..)
                try
                        ftp.Put(Stream,'img' + InttoStr(i+1)+ '.jpg');
                Except on E: Exception do
                        begin
                                Self.Error:='Error ' + E.Message + ' ' +
E.ClassName;
                                Synchronize(ShowError);
                                Self.Terminate;
                        end;
                end;
              (..)
The execute method Sleeps 500 ms check for if Terminate=false and do all
over again.

The problem is that the thread doens´t seem to abort the upload. They apper
to be waiting the transfer terminates. When the threads are finalized the
application stays a lot of time inside the loop:

While FtpThreadsCount>0 do Application.ProcessMessages.

The problem doesn't occur eveytime. Sometimes the thread are finalized fast
sometimes not. The network load seems to have something to do with that.
The main problem is when I need to close the application. It stays waiting
the threads finalize, and the user thinks that the application will never
close.

Somebody see another a way to fast abort the upload and terminate all
threads?

Thanks.

Replies