Solved

IdFtp 10 and Threads and Abort problem

Posted on 2006-06-14
13
1,320 Views
Last Modified: 2012-06-21
I'm using D7 and Indy 10. I am attempting the use of threads for
uploading files but I can't work out how to abort part way through
upload. Basically this is some code

type
  TFtpUpThread = class(TThread)
  private
    FFtp: TIdFtp;
  protected
    constructor Create(CreateSuspended: boolean);
    procedure Execute(); override;
  end;

type
  TForm1 = class(TForm)
//other usual gumph

var
  Form1: TForm1;

implementation

{$R *.dfm}

constructor TFtpUpThread.Create(CreateSuspended: boolean);
begin
  inherited Create(CreateSuspended);
  FFtp := Form1.IdFtp1;
  FreeOnTerminate := true;
end;

procedure TFtpUpThread.Execute();
begin
  FFtp.Put(FLocalName, FRemoteName, true);
  Terminate();
end;

procedure TForm1.btnUploadClick(Sender: TObject);
var
  ftd: TFtpUpThread;
begin
  ftd := TFtpUpThread.Create(false);
end;

procedure TForm1.btnAbortClick(Sender: TObject);
begin
  IdFtp1.Abort;
  IdFtp1.KillDataChannel;
end;

Trying various ways I get EAccessViolations or other various Id errors.
And the ftp is still working and cannot log in to server again even
with another ftp program. Any assistance especially including code
would be greatly appreciated. My brain hurts with this ;-)
0
Comment
Question by:xpher
  • 6
  • 4
  • 3
13 Comments
 
LVL 28

Expert Comment

by:2266180
ID: 16901678
well, firstly, indy is known to make radical changes from one major verision to the other, and often, that means that stuff that used to work before, no longer work (properly).

second, abort method by itself should do the trick.

here is my test case (delphi 7 + indy 9):

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
  IdFTP, IdAntiFreezeBase, IdAntiFreeze;

type
  TForm1 = class(TForm)
    IdFTP1: TIdFTP;
    IdAntiFreeze1: TIdAntiFreeze;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TFtpUpThread = class(TThread)
  private
    FFtp: TIdFtp;
  protected
    constructor Create(CreateSuspended: boolean);
    procedure Execute(); override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  ftd: TFtpUpThread;
begin
  IdFTP1.Connect();
  ftd := TFtpUpThread.Create(false);
  sleep(1000);
  IdFTP1.Abort;
end;

{ TFtpUpThread }

constructor TFtpUpThread.Create(CreateSuspended: boolean);
begin
  inherited Create(CreateSuspended);
  FFtp := Form1.IdFtp1;
  FreeOnTerminate := true;
end;

procedure TFtpUpThread.Execute;
begin
  FFTP.Put('s:\DSS-win-5.1.1.0127-jre142_07-Daily.zip');
  terminate;
end;

end.

works like a charm.
The main reason for which I stick with indy 9 and did not switch to indy 10 (though I tryied once), is exactly this: some stuff just stopped working. in my opinion, indy 9 is the most stable. I didn't try the latest releases of indy 10 (last time I tried was over a year back when it was in beta) so I can't say if they fixed their problems, but if my code (the way it is) does not work compied with indy 10, then it means they still have serious issues.
0
 
LVL 17

Expert Comment

by:TheRealLoki
ID: 16907644
xpher
fyi, you don't need the
terminate;
line at all, since this is in your thread's  "execute" method, when that method ends, it will terminate anyway.

-unrelated-
gotta agree with your comments re indy there ciuly.
my latest question to the indy team about our production release having an indy 10.052 ("stable" release) bug, was to use the latest indy 10 development snapshot... the changes between that release and the snapshot were huge. Not to mention the risks involved in using a build that has this big warning saying "hey we might be writing and making changes to these .pas files as you copy them, so warranty void m'kay".
0
 
LVL 1

Author Comment

by:xpher
ID: 16909908
Ciuly
Thanks for response. Obviously that idea won't work for aborting part way through as my original post. But it is interesting in the fact that yes it does work. The drawback is it only works once. If I run the project again the form does not show and my connection is constantly alive as in my original problem. If I disable my connection then re-enable it the project again only works once. I'm wondering if it's because the thread has to be aborted also?

TheRealLoki
Thanks for response. Don't you have to terminate it somewhere so it knows to free it?

I must admit I was wondering whether it would just be better to revert to Indy 9. But I must admit the connection seems faster with Indy 10.

Regards
0
Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

 
LVL 28

Expert Comment

by:2266180
ID: 16910078
weird again. my code worked for me fine every single time I run it. of course, I run it from the ide, but that doesn't make much difference in this case. I know that because I kept modifying the slep period to see that indeed it works. and yes, I had to manually delete the chunks of file that were left in a temporary form by the server
0
 
LVL 1

Author Comment

by:xpher
ID: 16910171
I ran it from ide and out of ide got same problems.
0
 
LVL 28

Expert Comment

by:2266180
ID: 16910324
yeah, but I run it with inde 9, not 10 ;)
you know, you could try installing another delphi instance with indy 9. I don't know if it's possible to install 2 different instances of the same version. you can try :)
0
 
LVL 1

Author Comment

by:xpher
ID: 16910445
It might be worth trying. Wont get chance for a day or two cos working.
0
 
LVL 17

Expert Comment

by:TheRealLoki
ID: 16915567
Using ciuly's code above on Delphi 7, Indy 9, I do not get any errors, but you have to close the socket like this after the abort command

procedure TForm1.Button1Click(Sender: TObject);
begin
  IdFTP1.Connect();
  ftd := TFtpUpThread.Create(false);
  sleep(1000);
  IdFTP1.Abort;
  IdFTP1.DisconnectSocket;
end;


Using ciuly's code above on Delphi 5, Indy 10.052, I have to close the socket like this
begin
  IdFTP1.Connect();
  ftd := TFtpUpThread.Create(false);
  sleep(1000);
  IdFTP1.Abort;
  IdFTP1.Socket.Close;
end;

The FTP Server reports a successful "ABOR" command for each version of Indy
0
 
LVL 17

Accepted Solution

by:
TheRealLoki earned 75 total points
ID: 16915590
oh and btw, no you do not need the "terminate;" line to free it.
The thread is set to terminated when the execute event ends, so the "freeonterminate := true;" code still applies.
you would set "dftp.terminated := true;" outside of your thread if you wished to terminate it (providing your execute method had code like
while not terminated do ...)
0
 
LVL 1

Author Comment

by:xpher
ID: 16923901
IdFtp1.Socket.Close disconnects IdFtp1 which is no good if have to reconnect to do anything else.

If I add another button and set its OnClick event to IdFtp1.Abort (removing abort from proc above) the program stops responding and connection stays alive.

Just out of interest what do you have in your uses clause (for version Indy 10.052)? Am I missing something?

My entries to do with IdFtp are

IdAntiFreezeBase, IdAntiFreeze, IdBaseComponent, IdComponent,
  IdTCPConnection, IdTCPClient, IdExplicitTLSClientServerBase, IdFTP
0
 
LVL 1

Author Comment

by:xpher
ID: 16925965
Well just downloaded Development Snapshot and everything works fine. Don't have to add IdFtp1.Socket.Close. I just use IdFtp1.Abort and it works everytime without leaving connection open. Also as a p.o.i the LogEvent is much easier to use just as in Indy9.

To thank you both for your input I'm feeling I should split points. Please both post feelings on this.

Cheers
Chris
0
 
LVL 28

Assisted Solution

by:2266180
2266180 earned 75 total points
ID: 16926405
I'm fine with that. but it is you the one who has to decide this. if you feel you have to split, then split.
all you have to decide is who helped you, and award accordingly.
0
 
LVL 1

Author Comment

by:xpher
ID: 16979823
Hope point share worked Ok never done it before. It was helpful that both of you tried things and let me know the outcome allowing me to test if it was my error.

Many thenks both.
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Delphi application Soap connection 5 102
find a node in VST 2 68
Firemonkey allowing RTL on android 6 28
scroll down TListBox component in Delphi 1 6
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…

815 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now