问题标签 [omnithreadlibrary]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
1245 浏览

multithreading - 如何清空 OmniThreadLibrary 线程池队列?

我刚刚发现了 OmniThreadLibrary 并开始使用它。我正在尝试启动最多不超过 20 个任务并将其余任务发送到队列中。

我修改了 OmniThreadLibrary 的00_Beep项目来做到这一点:

它有效,但如果我将任务数(即 TASKS_COUNT)增加到 7000,我会得到一个异常:

TOmniCommunicationEndpoint.Send: Queue is full

我阅读了我能找到的所有内容(OTL 博客和论坛、示例项目、google 了很多等等),似乎为了防止这种情况,我必须定期清空队列。

所以我尝试了这个,但没有奏效:

关于如何清空队列并避免此异常的任何建议?

知道有些人可能会说队列中的大量任务是荒谬的,足以说这既不是假设性问题,也不在我的问题范围内告诉我重新设计我的应用程序,此时我只需要知道OTL中排队系统的限制以及如何绕过这个限制。

提前致谢!

0 投票
1 回答
219 浏览

multithreading - Delphi 2010中其他线程的执行点

我正在使用 Delphi 2010(使用出色的 OmniThreadLibrary)开发一个多线程客户端应用程序,并且由于我不断地从一个线程切换到另一个线程,因此我很难进行调试。

我想知道是否有可能(使用任何工具或插件,我不在乎!)找到当前执行点,不仅针对当前线程,还针对所有其他线程。

一个简单的例子/报告:

我的目标是“查看”当 Delphi 在某个断点处停止时其他线程在做什么,而不仅仅是使用日志(或不那么有用的线程 12345 停止),而是像断点在它们处停止一样检查它们。

我希望我的问题足够清楚,请注意这里已经过了午夜,所以如果我的问题听起来很愚蠢,请不要怪我!

0 投票
2 回答
1353 浏览

multithreading - 如何使用 Delphi 和 OmniThread 在后台将文件上传到 azure?

我曾尝试使用 Delphi 将 +100 个文件上传到 azure。但是,这些调用阻塞了主线程,所以我想通过异步调用或后台线程来做到这一点。

这就是我现在所做的(就像这里解释的那样):

但是这个块也是(为什么?我不明白)。

0 投票
2 回答
1203 浏览

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

我使用优秀的 OmniThreadLibrary 库来实现线程源代码解析,程序需要放弃现有的解析并在源代码更改时重新开始解析。

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

提前致谢!

编辑1:很抱歉重新打开这个问题,但我发现内存泄漏时FParserThread没有通过调用该Terminate方法并给定足够的时间自行完成......关于什么可能导致内存泄漏的任何想法?谢谢!

编辑2:阅读这篇博文,我仍然无法弄清楚问题可能是什么,因为在ThreadedParse代码中的每一步之后如果Terminated是真的......

编辑 3:回答 Rob 的问题:

  1. 在 OnTerminated 事件处理程序(此处未显示)中,FParserThread 设置为“nil”,因此“FParser 自行完成”是指该if FParserThread <> nil then块未执行,在这种情况下,FParserThread 被终止,因为它的解析已完成。

  2. 代码背后的逻辑是,这是一个代码编辑器,在任何代码编辑时都会启动一个线程来将源代码解析为内部树表示,以防发生新的代码编辑但之前的解析线程没有被编辑过,程序会先强制上一个解析线程再启动一个新的解析线程。这可能不是一个好方法......

编辑4:在阅读了这个类似的SO问题之后,我将代码更改为FParserThread.Terminate不带参数的调用,这意味着,如果我理解正确,该语句只会发出线程结束的信号,并且在实际线程任务中,我将逻辑应用于如果Terminated属性为,则退出线程执行True

现在的连线是,在Tracetool的帮助下,我发现在调用事件(我清理内存FParserThread.TerminateOnTaskMessage地方)后不会再次触发,这就是导致内存泄漏的原因......

0 投票
1 回答
7087 浏览

multithreading - 让 Delphi TTimer 与多线程应用程序一起工作

我有一个简单的 TTimer 问题,该 TTimer 已启动并在主应用程序线程中执行其 OnTimer 事件,代码如下所示:

当我在一个简单的项目/演示中执行代码时,一切正常,但在我的应用程序(使用 Omni Thread Library v3)中,计时器事件永远不会被触发

我很确定它什么都没有,我只是不知道出了什么问题!

我三重检查:MyTimer在我的代码中只分配一次,它的 OnTimer 事件被正确分配,等等......

我正在使用德尔福 2010

任何人都知道如何解决这个问题?

0 投票
3 回答
1050 浏览

multithreading - OmniThreadLibrary:如何检测所有递归调度(=pooled)线程何时完成?

假设我必须在后台递归迭代存储在树结构中的项目,并且我想使用线程池中的多个线程(每个“文件夹”节点一个线程)遍历这棵树。我已经设法使用 OmniThreadLibrary 提供的几种不同的低级和高级方法来实现这一点。

但是,我还没有弄清楚如何正确地检测到扫描实际上已经完成,即每个最后的叶节点都已被处理。

我在网上找到了各种例子来检查是否GlobalThreadPool.CountExecuting + GlobalThreadPool.CountQueued <= 0使用了IOmniTaskGroup.WaitForAll(). 不幸的是,这些方法似乎都不适合我。检查总是返回True得太早,即当仍有一些任务在运行时。我看过的所有例子都没有使用递归——以及那些没有使用线程池的例子——这可能不是一个好的组合吗?

这是我目前正在尝试执行此操作的(非常)简化的示例代码片段:

我尝试过的等待的一个示例实现是这样的(基于在 About.com 上找到的示例):

但这似乎总是在“根线程”完成后立即退出。即使我使用Sleep()-calls 添加人为延迟,它仍然总是过早退出。似乎在从执行任务列表中删除的一项任务与在该任务中安排的要添加到排队任务列表中的任务之间存在“差距”......

实际上,与其等待扫描完成,我更喜欢使用事件处理程序(另外,我宁愿不使用Application.ProcessMessages,因为我在无表单应用程序中也需要它)并且我已经尝试过两者IOmniTaskControl.OnTerminated并且使用 a TOmniEventMonitorbut 因为这些火为每一个完成的任务我仍然需要以某种方式检查当前的是否是最后一个,这再次归结为与上述相同的问题。

或者有没有更好的方法来创建可以避免这个问题的任务?

0 投票
1 回答
350 浏览

delphi - OmnithreadLibrary 是否支持“工作窃取”?

例如,在 Java 平台上的 Fork / Join 框架中可以使用工作窃取。(请参阅Fork /join framework 如何比线程池更好?) - OmniThreadLibrary 是否有类似的可能?


工作窃取:无事可做的工作线程可以从其他仍在忙碌的线程中窃取任务。

0 投票
1 回答
818 浏览

multithreading - 如何在 OmniThreadLibrary 3 中暂停/恢复线程?

我希望主应用程序线程能够暂停/恢复其他工作线程,假设这是可能的,那么最好的方法是什么?

任何适用于 Windows XP(及更高版本)的建议都将受到欢迎!

PS。我正在使用Delphi 2010OmniThreadLibrary 3

0 投票
0 回答
598 浏览

delphi - 如何最好地使用 Omnithread 转换多个 Delphi TTimer 后台扫描任务

我已经开始考虑使用 Omnithread 来使用多线程改进我的 Delphi 应用程序。文档很好地涵盖了创建一个或多个工作任务,因此我从按钮单击调用的长操作可以替换为此演示代码(Async、CreateTask 等)。我遇到的困难是如何替换我最“混乱”的代码,其操作如下。

我有一个对应于硬件模块的单个类实例的概念。该类发布了一个或多个属性,这些属性公开了硬件的当前值和设置。属性可能是只读的或读/写的。对于这些类实例中的每一个,可以有从零到几个可见的显示表单。显示表单具有 TTimer 和上述已发布属性的内置列表。该列表被迭代以匹配适当命名的控件,例如标签或编辑控件,并且使用 RTTI 机制来获取和设置控件及其属性之间的值。结果是一个表单,它为实际硬件模块提供了一个很好的 UI,其副作用是可以打开多个表单,修改其中一个表单上的数据会导致其他表单在不久之后显示该数据。此属性监视由 TTimer 以 300 ms 的间隔滴答执行。每个刻度使它扫描类的所有属性并刷新其窗体上的匹配控件。计时器在打开表单的生命周期内运行。表单在需要时创建然后释放(这具有有用的性能优化,即在没有打开表单来检查硬件的情况下,应用程序必须尽可能快地运行,因为没有监控任务可以运行)。

有没有更好的方法使用线程来访问我发布的属性,而不是在 UI 线程中使用 TTimer?或者同步问题是否会超过任何优势?如果线程很有用,如何创建重复任务,例如模拟滴答计时器?

0 投票
0 回答
684 浏览

delphi - 如何用 OmniThreadLibrary 替换 TThread?

我习惯于创建 TThread 后代来执行持久的数据库操作。我通常的构造如下所示:

然后我显然使用这个类

当然,我通常将 DBOp 设置为另一个组件 var,以便能够终止或 WaitFor 线程。

现在我想重写这些 TThread 类并使用与 OmniThreadLibrary 类似的构造。我该怎么做?我的意思是:使用什么基类来定义所有类组件和属性?- 应该是 TOmniWorker 的后代吗?那么 Execute 程序在哪里呢?- 它应该是 TObject 的后代,然后将 OTLTaks 创建为CreateTask(DBOp.Execute)?- 它应该是我作为参数传递给 OTLTask 创建的 TObjectCreateTask(anonymous method that reads the parameter and calls its Execute)吗?

感谢您的任何提示。

编辑:(基于 gabrs 对澄清的评论)我的观点是,OTL 源代码中的所有样本/测试都只显示了一个简单的用法。主要是基本的“单一过程”线程。对于我的情况,我需要一个相当复杂的类,其中包含所有在线程中运行的子组件和子例程。我正在寻找这样的类祖先及其设计模式。