0

I would like to ask few questions, let me explain things to you first and you can see the questions below this post. I created a multi threading app which reads and update data from a database. The threads communicates with the main thread using sendmessage. I am passing a pointer TRecord to sendmessage and dispose the pointer in the main thread. Below are code snippets that shows the structure of the process:

const WM_MY_MESSAGE = WM_USER + 0;

PTestPointerRecord : ^TTestPointerRecord;
TTestPointerRecord = record
  i : integer;
end;

Here is the execute event of the extended TThread class. It will run continuously unless the thread was paused or terminated.

procedure TSampleThreadClass.Execute;
var
  TestPointerRecord : PTestPointerRecord;
  FConnection : TConnectionObject;
  FQuery : TQueryObject;
begin
  while not Terminated do
  begin
    New(PTestPointerRecord);
    FConnection := TConnectionObject.Create(nil);
    FQuery := TQueryObject.Create(nil);
    try
      FConnection.connectionstring := 'path';
      FConnection.loginPrompt := False;
      FConnection.open;

      FQuery.connection := FConnection;
      FQuery.close;
      FQuery.sql.clear;
      FQuery.sql.add('select column1, column2 from table');
      FQuery.open;

      PTestPointerRecord.i := 0;
      SendMessage(frmMain.handle, WM_MY_MESSAGE, 0, integer(PTestPointerRecord));
    finally
      FQuery.close;
      FConnection.disconnect;

      FreeAndNil(FQuery);
      FreeAndNil(FConnection);

      sleep(250);
    end;
  end;  
end;

Here is the event that receives the message from the thread.

procedure TfrmMain.message(msg : TMessage);
var
  TestPointerRecord : PTestPointerRecord;
begin
  TestPointerRecord := PTestPointerRecord(msg.lParam);
  try
    edit1.Text := inttostr(TestPointerRecord.i);  
  finally
    Dispose(TestPointerRecord);
  end;
end;

The app will be used as a service type application that will run continuously all time.

Questions:
1. Am I disposing the pointer properly?
2. When I checked my task manager while the app is running, I observed that under Processes Tab, I notice that Memory(Private working set) increases continuously. Is this fine?

Regards to all

  • 1
    The call to Dispose is fine. The big problem is the window handle may be recreated. Disaster if that recreation happens in the thread. You need to use a dedicated window handle created by calling AllocateHWnd. – David Heffernan Oct 30 '18 at 07:11
  • Of course, since you send the message, the thread is blocking until the message has been processed. So there's no need to dispose in the main thread. You can dispose in thread. Indeed you don't even need dynamic allocation. A local variable is fine. – David Heffernan Oct 30 '18 at 07:26
  • @DavidHeffernan hi, thanks for the response. I saw this answer from a related post, https://stackoverflow.com/a/19063457/5056112. I saw you arguing with someone in this post. I was wondering, the alternative answer that Remy posted here, which i think the same thing you are trying to tell me right now, do you think, it is ok to use? Is it not really going to cause a memory leak? Thanks – Francis Carillo Oct 30 '18 at 23:28
  • There the code uses PostMessage which is async. As for the questions you raise in the comments, read my earlier comments above. – David Heffernan Oct 30 '18 at 23:32
  • @DavidHeffernan yes It's PostMessage. What I'm trying to tell you is the creation of window handle. I was wondering if I can use the same way remy created a window handle in the post? – Francis Carillo Oct 30 '18 at 23:36
  • Yes you can. AllocateHWnd. As per my comment also. – David Heffernan Oct 30 '18 at 23:58

1 Answers1

1

I tried suggestion of David Heffernan about using a separate handle rather than using the main form's handle. This suggestion did not really solved the problem BUT thanks to David, it is worth using since he made a big point about problems that might occur when the main form's handle was used to received a message and the window was redrew or recreated.

Through deeper exploring of my codes through, debugging, trial and error. I found that the problem was reoccurring when I create the connection and query the database. Note, I am using ZeosLib to connect to the database, and seems that every time my thread loop, do the database operations, the working private memory keeps on increasing which is I'm not sure if Zeoslib is thread safe at all. So I switched to ADO and everything went well. The working private memory stays to a stable amount.

Thanks for all the help.