线程应用程序中的 Indy 错误!

发布于 2024-08-07 06:56:07 字数 998 浏览 2 评论 0原文

当 TidHTTP 在 GET 后等待服务器的响应并且线程被终止时,我遇到了一些与 TidHTTP 相关的内存泄漏。

示例:

aThread = class(TThread) 
private  
  FidHTTP :TidHTTP;   
  FCommand :String;
public   
  procedure Execute(); override;   
  constructor Create(aCommand :String); override;
  procedure Disconnect;
end;

procedure aThread.Execute();   
  var response :String; 
begin   
  response := FidHTTP.Get(FCommand); 
end;

procedure aThread.Disconnect;
begin
  if ((FidHTTP <> nil) and (FidHTTP.Connected)) then FidHTTP.IOHandler.CloseGracefully;
end;

constructor aThread.Create(aCommand :String); override; 
begin   
  FCommand := aCommand;    
  inherited Create; 
end;

当应用程序关闭时,我用此停止线程:

aThread.Disconnect;
aThread.Terminate;
aThread.Free;

我应该做什么来解决内存泄漏?

FastMM4 Log :

13 - 20 bytes: TIdThreadSafeInteger x 1
21 - 36 bytes: EAccessViolation x 1, TIdCriticalSection x 2
181 - 212 bytes: UnicodeString x 1

谢谢 :)

I've got some memories leak related to TidHTTP when it's waiting for the response of a server after a GET and that the thread is being terminated.

Example :

aThread = class(TThread) 
private  
  FidHTTP :TidHTTP;   
  FCommand :String;
public   
  procedure Execute(); override;   
  constructor Create(aCommand :String); override;
  procedure Disconnect;
end;

procedure aThread.Execute();   
  var response :String; 
begin   
  response := FidHTTP.Get(FCommand); 
end;

procedure aThread.Disconnect;
begin
  if ((FidHTTP <> nil) and (FidHTTP.Connected)) then FidHTTP.IOHandler.CloseGracefully;
end;

constructor aThread.Create(aCommand :String); override; 
begin   
  FCommand := aCommand;    
  inherited Create; 
end;

I stop the thread with this when the application close :

aThread.Disconnect;
aThread.Terminate;
aThread.Free;

What should I do to solve the memories leaks ?

FastMM4 Log :

13 - 20 bytes: TIdThreadSafeInteger x 1
21 - 36 bytes: EAccessViolation x 1, TIdCriticalSection x 2
181 - 212 bytes: UnicodeString x 1

Thanks :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

左秋 2024-08-14 06:56:07

您应该

aThread.WaitFor;

在销毁线程之前调用。这可确保线程正确终止。销毁线程而不终止它可能会导致执行方法中的访问冲突,从而导致 FastMM 显示内存泄漏。

编辑 考虑到问题可能是执行方法中的阻塞调用,您可能需要将 TIdHttp.ReadTimeOut 设置为合理的时间并定期检查线程是否终止。

You should call

aThread.WaitFor;

before destroying the thread. This makes sure that the thread properly terminates. Destroying the thread without terminating it probably causes an access violation in the execute method, which results in the memory leaks displayed by FastMM.

EDIT Considering the fact that the problem might be the blocking call in your execute method, you might want to set TIdHttp.ReadTimeOut to a reasonable time and check for thread termination in regular intervals.

記柔刀 2024-08-14 06:56:07

Indy 还会产生两到三个预期的内存泄漏,例如整数和临界区。但它们可能已按预期注册,也可能未注册。所以我不知道这些是不是你看到的。如果您运行代码 5 次,您会看到比现在更多的泄漏吗?

至于Smasher建议的WaitFor,在调用Free之前先调用。这不应该是必需的,也不应该是问题的原因,因为如果您检查 TThread 的析构函数,您将准确地看到已经完成的操作。

我真的不知道为什么你的泄漏报告中会出现访问冲突。但是,您正在从线程外部调用 Disconnect,而 Indy 组件正在您的线程中使用。不要这样做,从不同线程使用相同的非线程安全组件会带来麻烦。这可能会导致您的访问冲突泄漏。让线程本身执行对 Indy 组件的所有调用。

按照 Smasher 的建议减少 ReadTimeOut 是一个好主意,但可以确保您的应用程序不会阻塞太久。

Indy also produces two or three expected memory leaks, like the integer and the critical section. But they might or might not have been registered as expected. So I can't tell if these are the ones you see. If you would run your code 5 times, would you see more leakage than you are seeing now?

As for the WaitFor suggested by Smasher, to call before calling Free. This should not be needed, nor the cause of your problems, because if you check the destructor of TThread, you will see exactly that is already done.

Why you are getting an Access Violation in your leak report, I don't really know. However, you are calling Disconnect from outside of your thread, while the Indy component is in use in your thread. Don't do that, using the same non-thread-safe components from different threads is asking for trouble. This might cause your Access Violation leaking. Let the thread itself do ALL the calls to the Indy component.

Reducing the ReadTimeOut as suggested by Smasher is a good idea however to make sure your application doesn't block too long.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文