如何使用OmniThreadLibrary访问线程变量?

3
这似乎是一项简单的任务,我只是不知道该如何使用OmniThreadLibrary开始:

我创建了一个在后台执行某些处理的任务。结果存储在任务类的字段中,并不断填充新值。

现在主线程想要定时读取这些字段并显示它们的值。
因此,它需要访问这些字段并确保在这些时刻它们没有被写入(同步)。

如何使用OmniThreadLibrary实现这一点?

2个回答

3

在OTL中,没有直接支持所有者/线程数据共享的功能,因为我的多线程经验告诉我这总是一个不好的做法。(有时候是唯一的解决方案,但仍然是不好的。)

你应该采用第二个mghie的建议 - 创建一个(可选基于接口的)对象,并将此对象(或其接口)传递给线程。类似于这样:

sharedData := TSharedData.Create;
task := CreateTask(worker).SetParameter('shared', sharedData).Run;

工作进程:

sharedData := Task.Param['shared'].AsObject as TSharedData;

另一种解决问题的方法是在用户按下“立即更新”按钮时向任务发送“请发送更新”消息。该任务将回复一个包含当前状态的对象。但是,如果任务执行的计算需要很长时间且无法中断,则此解决方案并不适用,共享状态的方法更为有效。

2

请查看OTL测试23,它实现了一个后台文件搜索。使用SetParameter()方法来设置搜索属性,使用Comm通道将结果传输回主线程。通信已经是线程安全的,无需实现任何进一步的同步。

编辑:

如果你不想要推送模型而是拉取模型,那么你当然可以使用标准的同步工具:一个具有关键部分的对象,在所有访问器中使用以保护数据免受并发访问。这个对象可以是任务对象本身,也可以是由GUI线程创建并通过调用SetParameter()传递给任务的任何第三个对象。如果你不使用一个对象而是一个接口指针,那么你将获得更多的安全性,因为销毁顺序将不再重要,持有数据的对象仅在最后一个对其实现的接口的引用被重置时才会被销毁。


据我理解这个演示,任务会在有新的结果时将其结果发送回主线程。在我的情况下,只有当操作员按下更新按钮时,即每创建1000个新值时,主线程才需要获取当前值。如果主线程只在需要时读取值会更好。 - Holgerwa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接