I don't understand why I'm getting EAccessViolation. This happens when closing my application.

I don't understand why I'm getting EAccessViolation. This happens when closing my application.

I'm basically displaying frames. I'm calling a "Start" method after displaying them.

procedure TfrPicpic.Start;
begin
if Assigned(AnonymousThread) then
AnonymousThread.Terminate;

pnDeviceNotReachable.Visible := false;
pnDeviceNotReachable.Align := alNone;
AnonymousThread := TThread.CreateAnonymousThread(
procedure()
var
isopen: boolean;
begin

while not AnonymousThread.CheckTerminated do
begin
if Assigned(Connection) then
isopen := PortIsOpen(5432, Connection.Server);

AnonymousThread.Synchronize(nil,
procedure()
begin
if not isopen and Assigned(pnPicpicEteinds) then
begin
pnDeviceNotReachable.Align := alClient;
pnDeviceNotReachable.Visible := true;
end
else
begin
pnDeviceNotReachable.Visible := false;
pnDeviceNotReachable.Align := alNone;
end;
end);
sleep(500);
end;
end);

AnonymousThread.Priority := tpLower;
AnonymousThread.FreeOnTerminate := false;
AnonymousThread.Start;
end;


Prior destroying them, I'm calling the "Stop" method :

procedure TfrPicpic.Stop;
begin
if Assigned(AnonymousThread) then
AnonymousThread.Terminate;
end;

destructor TfrPicpic.Destroy;
begin
stop;
inherited;
end;

What's going wrong ?

Comments

  1. Do some debugging. Get a call stack when the exception is raised.

    ReplyDelete
  2. Lars Fosdal or you could just call Free on the thread and have it all happen that way.

    ReplyDelete
  3. Stéphane Wierzbicki Hard to debug away from your computer. Anyway, the point remains. Before solving a problem, first identify it. In this case the way to do that is through debugging. Get that stack trace, and take it from there.

    ReplyDelete
  4. David Heffernan I totally agree but it's hard to be in front of it's computer from 7.30am to 8.30pm .... ;). Call stack was limited to 3 entries (from memory) :

    CheckTerminated
    Synchronized
    TControl.SetVisible

    And I jumped into the ASM view...

    Thing was that my theads were still running after the application termination. Adding Thread.WaitFor solved my issue (I don't know why I forgot this as it is not the first time I work with worker thread...)

    Thank to all of you

    ReplyDelete
  5. Your code doesn't appear to destroy the thread so it leaks. You can replace Termainte and WaitFor with a single call to Free on the thread. The destructor of TThread calls Terminate and WaitFor.

    ReplyDelete
  6. David Heffernan yes ! will do so... thank you

    ReplyDelete

Post a Comment