0

我想问几个问题,让我先给你解释一下,你可以看到这篇文章下面的问题。我创建了一个多线程应用程序,它从数据库中读取和更新数据。线程使用 sendmessage 与主线程通信。我将指针 TRecord 传递给 sendmessage 并将指针放在主线程中。以下是显示流程结构的代码片段:

const WM_MY_MESSAGE = WM_USER + 0;

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

这是扩展 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.当我在应用程序运行时检查我的任务管理器时,我观察到在进程选项卡下,我注意到内存(私人工作集)不断增加。这样好吗?

问候所有人

4

1 回答 1

1

我尝试了 David Heffernan 关于使用单独的句柄而不是使用主窗体的句柄的建议。这个建议并没有真正解决问题,但是感谢大卫,它值得使用,因为他对使用主窗体的句柄接收消息并且重新绘制或重新创建窗口时可能出现的问题提出了重要的观点。

通过对我的代码进行更深入的探索、调试、反复试验。当我创建连接并查询数据库时,我发现问题再次出现。请注意,我正在使用 ZeosLib 连接到数据库,并且似乎每次我的线程循环执行数据库操作时,工作私有内存都在不断增加,我不确定 Zeoslib 是否是线程安全的。所以我切换到 ADO,一切都很顺利。工作私有内存保持稳定的数量。

感谢所有的帮助。

于 2018-11-05T05:07:21.497 回答