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

标签 delphi omnithreadlibrary

我使用出色的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/

相关文章:

delphi - 如何修复 Nevrona Rave 中的无限打印循环错误

java - 线程中出现异常 "AWT-EventQueue-0"java.lang.UnsatisfiedLinkError : testmydll. TestDLL.a()I

delphi - 如何在类中正确实现 Set 作为属性?

multithreading - TOmniEventMonitor 可以在后台线程中使用吗?

multithreading - 如何使用OmniThreadLibrary设计 “conveyor”操作?

multithreading - 如何知道OmniThreadLibrary中Pipeline阶段的状态?

java - 当函数没有返回值时,Delphi XE2 是否正确从 Java/Axis2 导入 WSDL?

delphi - 以小时、分钟、秒为单位的日期时间之间的差异

multithreading - 主线程阻塞并行线程?

delphi - 使用 VirtualTreeview 和 OTL 的内存泄漏