gpt4 book ai didi

delphi - 这是使用OmniThreadLibrary的正确方法-终止现有的然后创建一个新的吗?

转载 作者:行者123 更新时间:2023-12-03 19:33:50 25 4
gpt4 key购买 nike

我使用出色的OmniThreadLibrary库来实现线程化的源代码解析,该程序需要放弃现有的解析,并在源代码发生更改时重新启动解析。

我使用下面显示的代码段执行此操作,这是正确的方法吗?我还需要检查Terminated函数中线程的ThreadedParseHtml属性吗?

if FParserThread <> nil then
begin
FParserThread.RemoveMonitor;
FParserThread.Terminate(500);
end;

FParserThread := CreateTask(ThreadedParse);
FParserThread.SetParameter('SourceCode', Editor.Lines.Text);
FParserThread.MonitorWith(FParserThreadMonitor);
FParserThread.Run;


提前致谢!

编辑1:很抱歉再次提出这个问题,但是当我没有足够的时间通过调用 FParserThread方法完成 Terminate本身时,我发现内存泄漏了。关于什么可能导致内存泄漏的任何想法?谢谢!

编辑2:阅读 this blog post,我仍然不知道问题可能出在哪里,因为在 ThreadedParse的每个步骤之后,如果 Terminated正确,代码就会中断...

编辑3:回答罗布的问题:


在OnTerminated事件处理程序(此处未显示)中,FParserThread设置为“ nil”,因此通过“ FParser自身完成”,我的意思是不执行 if FParserThread <> nil then块,在这种情况下FParserThread会终止,因为它已经解析了完成了。
代码背后的逻辑是,这是一个代码编辑器,在进行任何代码编辑时,都会启动一个线程将源代码解析为内部树表示形式,以防发生新的代码编辑但先前的解析很繁琐的情况。尚未编辑,该程序将首先强制使用先前的解析线程,然后再启动一个新的解析线程。这可能不是一个好方法...


编辑4:读取 this similar SO question后,我将代码更改为不带参数调用 FParserThread.Terminate,这意味着,如果我正确理解,该语句将仅指示线程结束,并且在实际的线程任务中,我应用了如果 Terminated属性为 True,则退出线程执行的逻辑。

现在连接的是,在 Tracetool的帮助下,我发现在调用 FParserThread.Terminate后,不会再次触发 OnTaskMessage事件(我在其中清理内存),这就是导致内存泄漏的原因... 。

最佳答案

您不必在关联的任务中检查Terminated属性。您正在调用Terminate(1),如果它未在指定的1 ms窗口内结束,则会强制杀死该线程。

但是,强制杀死线程实际上不是一个好主意。当您杀死该线程时,该线程可能拥有互斥体或关键部分,因此杀死该线程将使共享数据处于不一致状态。这可能会对您的整个程序产生不利影响。

更好的方法是通知线程您希望其终止,但给它一个更现实的终止期限。在另一个线程中,您应该偶尔检查是否要求该线程终止,然后让其正常终止。

如果线程没有在指定的时限内结束,则您遇到了更大的问题,强行杀死它并不能解决问题。

关于delphi - 这是使用OmniThreadLibrary的正确方法-终止现有的然后创建一个新的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9932013/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com