delphi xe2 правильное удаление указателя, созданного из потока, указатель которого отправляется в основной поток - PullRequest
0 голосов
/ 30 октября 2018

Я хотел бы задать несколько вопросов, позвольте мне сначала объяснить вам кое-что, и вы можете увидеть вопросы ниже в этом посте. Я создал многопоточное приложение, которое читает и обновляет данные из базы данных. Потоки связываются с основным потоком с помощью sendmessage. Я передаю указатель TRecord для отправки сообщения и распоряжаться указателем в основном потоке. Ниже приведены фрагменты кода, которые показывают структуру процесса:

const WM_MY_MESSAGE = WM_USER + 0;

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

Вот событие execute расширенного класса TThread. Он будет работать непрерывно, если поток не был приостановлен или прерван.

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;

Вот событие, которое получает сообщение из потока.

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

Приложение будет использоваться как приложение типа службы, которое будет работать постоянно постоянно.

Вопросы:
1. Правильно ли я выбрал указатель?
2. Когда я проверял свой диспетчер задач во время работы приложения, я заметил, что на вкладке «Процессы» я замечаю, что память (частный рабочий набор) постоянно увеличивается. Это нормально?

С уважением ко всем

1 Ответ

0 голосов
/ 05 ноября 2018

Я попытался предложить Дэвиду Хеффернану использовать отдельный дескриптор, а не дескриптор основной формы. Это предложение на самом деле не решило проблему, НО, благодаря Дэвиду, его стоит использовать, так как он высказал большое мнение о проблемах, которые могут возникнуть, когда для получения сообщения использовался дескриптор основной формы, а окно было перерисовано или заново создано.

Путем более глубокого изучения моих кодов, отладки, проб и ошибок. Я обнаружил, что проблема повторяется, когда я создаю соединение и запрашиваю базу данных. Обратите внимание, что я использую ZeosLib для подключения к базе данных, и кажется, что каждый раз, когда мой цикл потока выполняет операции с базой данных, рабочая частная память продолжает увеличиваться, и я не уверен, что Zeoslib вообще безопасен для потоков. Поэтому я перешел на ADO и все прошло хорошо. Рабочая личная память остается стабильной.

Спасибо за помощь.

...