这似乎是一项简单的任务,我只是不知道该如何使用OmniThreadLibrary开始:
我创建了一个在后台执行某些处理的任务。结果存储在任务类的字段中,并不断填充新值。
现在主线程想要定时读取这些字段并显示它们的值。
因此,它需要访问这些字段并确保在这些时刻它们没有被写入(同步)。
如何使用OmniThreadLibrary实现这一点?
我创建了一个在后台执行某些处理的任务。结果存储在任务类的字段中,并不断填充新值。
现在主线程想要定时读取这些字段并显示它们的值。
因此,它需要访问这些字段并确保在这些时刻它们没有被写入(同步)。
如何使用OmniThreadLibrary实现这一点?
在OTL中,没有直接支持所有者/线程数据共享的功能,因为我的多线程经验告诉我这总是一个不好的做法。(有时候是唯一的解决方案,但仍然是不好的。)
你应该采用第二个mghie的建议 - 创建一个(可选基于接口的)对象,并将此对象(或其接口)传递给线程。类似于这样:
sharedData := TSharedData.Create;
task := CreateTask(worker).SetParameter('shared', sharedData).Run;
工作进程:
sharedData := Task.Param['shared'].AsObject as TSharedData;
请查看OTL测试23,它实现了一个后台文件搜索。使用SetParameter()
方法来设置搜索属性,使用Comm
通道将结果传输回主线程。通信已经是线程安全的,无需实现任何进一步的同步。
编辑:
如果你不想要推送模型而是拉取模型,那么你当然可以使用标准的同步工具:一个具有关键部分的对象,在所有访问器中使用以保护数据免受并发访问。这个对象可以是任务对象本身,也可以是由GUI线程创建并通过调用SetParameter()
传递给任务的任何第三个对象。如果你不使用一个对象而是一个接口指针,那么你将获得更多的安全性,因为销毁顺序将不再重要,持有数据的对象仅在最后一个对其实现的接口的引用被重置时才会被销毁。