【问题标题】:Delphi XE + thread + idHttp without memory leaksDelphi XE + 线程 + idHttp 无内存泄漏
【发布时间】:2015-06-26 08:49:12
【问题描述】:

首先你好,我的英语很抱歉。 有人可以在执行中使用简单的 GET 与创建 + 销毁线程共享工作源吗?

我尝试自己做,但总是会出现内存泄漏((

我用源代码末尾的代码对其进行测试

initialization
  ReportMemoryLeaksOnShutdown := True;

顺便说一句,我用谷歌搜索了 2 周并测试了许多样本......并且默认情况下总是有泄漏 =(

delphi XE7 32bit at windows 7 x64

当我按下停止按钮时,我仍然看到一些连接

关闭后我收到此消息

无法发布图片,需要 10 声望...

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, sButton, sMemo, sEdit,
  sSpinEdit, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP,System.SyncObjs;

type
  TForm1 = class(TForm)
    StartBtn: TsButton;
    StopBtn: TsButton;
    ThreadCount: TsSpinEdit;
    sdt1: TsEdit;
    sm1: TsMemo;
    procedure StartBtnClick(Sender: TObject);
    procedure StopBtnClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

type
  Thread = class(TThread)
  private
   HTTP : TIdHTTP;
   result:integer;
   InputIndex:integer;
  public
     procedure Local;
     constructor Create(CreateSuspended:boolean);
     destructor Destroy; override;
  protected
     procedure Execute; override;


  end;


var
  Form1: TForm1;
  LocalWork: Boolean;
  target: string;

implementation

{$R *.dfm}



constructor Thread.Create(CreateSuspended: boolean);
begin

  Inherited Create(true);
  FreeOnTerminate:=true;

  HTTP:=TIdHTTP.Create(nil);
  HTTP.ReadTimeout := 2000;

  Resume;
end;


destructor Thread.Destroy;
begin


try

  If HTTP.Connected then
  begin
    HTTP.Disconnect(false);
    HTTP.IOHandler.InputBuffer.Clear();
    HTTP.IOHandler.Close;
    Terminate;
  end;
finally
  WaitFor;
  FreeAndNil(HTTP);
end;

inherited;
end;




procedure Thread.Execute;
begin

while (LocalWork=True) do
   begin
     if LocalWork=true then
        begin


          HTTP.Get(target);
          if HTTP.ResponseCode=200 then
              begin
                result:=1;
              end
          else
              begin
                result:=2;
              end;


          Synchronize(Local);
        end
     else
        begin

          EndThread(0);
        end;


   end;
EndThread(0);
end;




procedure Thread.Local;
begin

if result=1 then Form1.sm1.Lines.Add('Good ');
if result=2 then Form1.sm1.Lines.Add('Bad ');
end;




procedure TForm1.StartBtnClick(Sender: TObject);
var
i:integer;
begin
  target := sdt1.Text;
  LocalWork := True;
  for I := 0 to ThreadCount.Value-1 do
  begin
    sm1.Lines.Add('Thread createrd '+inttostr(i));
    Thread.Create(true); // создаем замароженный поток
  end;



end;



procedure TForm1.StopBtnClick(Sender: TObject);
begin
LocalWork:=false;

end;


initialization
ReportMemoryLeaksOnShutdown := True;

end.

【问题讨论】:

  • 如果您能向我们展示您的代码,这样我们就可以看到这些内存泄漏可能源自何处。
  • 无需在Execute方法中调用EndThread。不要在销毁析构函数中调用terminatewaitfor。在TThread.Create 中调用inherited Create(false),最后不要调用Resume
  • 谢谢回答!现在我只得到这个泄漏s21.postimg.org/9c9ts58pz/screenshot_911.png

标签: multithreading delphi memory-leaks


【解决方案1】:
  • 在线程构造函数中,调用inherited Create(false);。最后跳过Resume 电话。在构造函数完成之前,线程不会启动。
  • 在线程Execute 方法中,跳过EndThread 调用,因为当Execute 方法结束时线程会处理这个问题。
  • Destroy 析构函数中,不要调用TerminateWaitfor。他们根本不属于那里。该线程被告知FreeOnTerminate,并且会优雅地这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-12
    • 2014-10-29
    • 2013-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多