【发布时间】:2012-03-29 19:20:34
【问题描述】:
我使用优秀的 OmniThreadLibrary 库来实现线程化源码解析,程序需要放弃现有的解析,每当源代码发生变化时重新开始解析。
我使用下面显示的代码 sn-p 执行此操作,它是正确的方法吗?我还需要检查ThreadedParseHtml函数中线程的Terminated属性吗?
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:回答 Rob 的问题:
-
1234563被终止,因为它的解析已经完成。
代码背后的逻辑是,这是一个代码编辑器,在任何代码编辑时,都会启动一个线程将源代码解析为内部树表示,以防新代码编辑发生但之前的解析线程没有被编辑,程序将首先强制之前的解析线程然后启动一个新的解析线程。这可能不是一个好方法...
编辑 4:阅读this similar SO question 后,我将代码更改为不带参数调用FParserThread.Terminate,这意味着,如果我理解正确,该语句只会发出线程结束的信号,在实际的线程任务中,如果Terminated 属性为True,我应用逻辑退出线程执行。
现在的连线是,在Tracetool 的帮助下,我发现在调用FParserThread.Terminate 之后OnTaskMessage 事件(我清理内存的地方)不会再次触发,这就是导致内存泄漏的原因....
【问题讨论】:
-
好的,我想我必须在解析例程中检查 Thread 对象的 Terminiated 标志...
-
请添加有关新信息的更多详细信息。 FParserThread “自行完成”是什么意思,为什么要让 FParserThread 调用 Terminate?
-
Rob,我添加了 Edit 3 来回答您的问题,感谢您对迟到的回复感到抱歉。
-
OK,最后,我发现问题的发生是因为没有触发 OnTaskMessage 事件,在调用 Terminate() 方法之后...我找到了一个workround - 在线程任务执行代码中,在如果线程被终止,那里有空闲的内存......