Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 166
  • Last Modified:

Thread Exiting Problems

Hello,

    I have a thread which does some painting on the screen. During the Execute method I repeatedly call a procedure (which is in another unit). This procedure itself has a longish (1 or 2 seconds) for...do loop, and I need to include Application.ProcessMessages in this loop, because if the user clicks the form during this loop, I want the application to end (a la screensaver). So in the execute method of MyThread I have:

 while not Terminated do begin
      Synchronize (PaintIt);
      Delay(1000)           // 1 second
 end

PaintIt is a thread procedure which has the following code:

//some code before this
PaintLoop(Canvas);

and finally, PaintLoop, is a procedure in another unit which looks like:

for i := 1 to 1000 do begin
  BitBlt(bla bla bla);
  Application.ProcessMessages;
end;

So, in the mouse click event of the main form, I say:

MyThread.Terminate;
Close;

The PROBLEM is that after the FormClose event, the application doesn't end, and attempts to go back to the for...do loop in the PaintLoop procedure. Problem, of course, is that all of the canvases have by now been Free'd, and I therefore get an access violation. Why is it going back to the for...do loop, and what can I do to stop this!?

Note: If I click on the form after the for...do loop (i.e. during the 1 second delay) then the application terminates nicely.
0
wolfcrag
Asked:
wolfcrag
1 Solution
 
JimBob091197Commented:
It would appear that your for loop in PaintIt needs to get all the way to 1000, even if the thread terminates when i = 10.

Here are 2 possible solutions:
1)  Change the for loop in PaintLoop to a while loop, and exit the loop early if the thread terminates.

2)  Create a variable or something which the thread sets to True when it's finished.  E.g. In your form's MouseClick event add the following:
    MyThread.Terminate;
    while  not OkToExit  do
        Application.ProcessMessages;
    Close;
Your thread's Execute method would then look something like this:
    OkToExit := False;
    while not Terminated do begin
        Synchronize(PaintIt);
        Delay(1000);
    end;
    OkToExit := True;

0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now