Link to home
Start Free TrialLog in
Avatar of imnotapro
imnotapro

asked on

Cancel a TThread in middle of execution!

Ok, I got a little problem. I do work on an application which is going to download different stuff from the internet, and I got a little problem with the threads. I use some classes that can use up to 5 seconds to complete (like Connect), and it all runs after eachother (not a big loop for the entire thread, but a task, start to end). Therefore I can't use the easy, classic, Cancel := True, if cancel = True then Exit; way. I did try most procedures in TThread to cancel it, like Terminate, DoTerminate, Suspend, etc..., but none of them seems to cancel it. Is there some not too hard way to simply terminate/cancel, and then free the Thread without having to add extra If Cancel = True ..... code in the Execute procedure (I can't do that, because it doesn't run in a loop, and some of the procedures inside that thread takes time to do, and I can't do that If Cancel = True between each line of code). 400 points for this working answer.

Another extra question, worth 100 points, what is the difference between Destroy, and Free when I free a component, or class (like TMemoryStream)? Which of them frees it fully (returns just as many bytes as it took when I created it)?
SOLUTION
Avatar of ceoworks
ceoworks

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ceoworks
ceoworks

I'm not sure if i completely understand your question but you may think to use this code :

MyThread.FreeOnTerminate := True;
..
MyThread.Suspend;
MyThread.Terminate;
..
Avatar of imnotapro

ASKER

Ceoworks: Thanks for this nice answer. I'll accept your answer (guarantied) when I get the other answer (it's not possible to accept one at time).

Ceoworks again: Okay, I'll try that now.
Ohh i understand what you meant when you say that stop execution of internet related things and free them. In 5 min, i'll go back to home and if i'll have time i'll try to develop a little sample for you.

Cheers,

Oktay
Okay, with the first question I need a bit more help. Take a look at this:

procedure Tdownloader.Execute;
begin
  ...
  //Here we get some instance where this download fails, and therefore I want it to kill itself, and free completly
  //The ID variable is declared in the Type, and contains (100% sure) it's own number in it's array of Tdownloader.
  KillDownloadHandle(ID);
  ...
end;

procedure KillDownloadHandle(ID: Integer);
begin
  //Here I tried what you suggested:
  download[ID].Suspend;

  freeandnil(download[ID]);
end;


I think that part is a bit dumb, cuz when the thread is going to kill itself, I just proved that it stops on Suspend, which again causes that it never runs freeandnil. Will FreeOnTerminate make sure it gets freed then? Or should I do something like this:

procedure KillDownloadHandle(ID: Integer; Myself: Boolean);
begin
  if myself=True then
  begin
    exit;   //Simply let FreeOnTerminate free it
  end else begin
    download[ID].Suspend;
    freeandnil(download[ID]);
  end;
end;


Would that make that part memoryleakfree (I know it frees the entire application automatically on exit, but this application can run LONG without being closed, so everything should be leak-free)?
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Okay, that helped a lot :). One more thing, what's the difference between Suspend and Terminate here?

The points are yours :).
Before i see your last post, i had send this answer. I can give you a detailed answer after 1-2 hour because i'm ready to go back to home now. Until that time, you may wants to try the logic of my last code.. Sorry but I really hurry and i don't have time to think about your last code. I'll try to make it all clear for you then.

Cheers,

Oktay

Suspend stops the execution of your thread then it become safe for you to Disconnect and FreeAndNil your sockets. At the final you are calling Terminate and then your thread frees itself.

I'm glad to hear that you problem solved :)

Have a nice day,

Oktay Sancak
Sorry i was hurried when i was typing this code so it needs a little fix :

  TMyThread = class(TThread)
  private
    FSocks: array[0..2] of TIdTCPClient;
  protected
    procedure Execute;
  public
    constructor Create(ConnIP: string; ConnPort);
    procedure StopConnections;
  end;
 
  should be :

  TMyThread = class(TThread)
  private
    FSocks: array[0..2] of TIdTCPClient;
    procedure Execute; override; // override
  public
    constructor Create(ConnIP: string; ConnPort: integer); // and type of ConnPort
    procedure StopConnections;
  end;

Rgds,

Oktay
Thanks, you've really been helpful, you deserve those 500 points :).

I got a system very similar to yours with a few modifications (to suit my previous setup), and it's all working now, 100% failsafe. Thanks :).
To be helpfull is more important than points. I'm really glad to hear that your problem solved.. :)

Have a nice day,

Oktay Sancak