这似乎是一件容易的事,我只是不知道从哪个方向开始使用OmniThreadLibrary:
我创建了一个在后台进行处理的Task。结果存储在任务类的字段中,并不断填充新值。
现在主线程想要阅读这些字段并不时显示它们的值 因此,它需要访问这些字段并确保在这些时刻不会写入它们(同步)。
如何使用OmniThreadLibrary完成这项工作?
答案 0 :(得分:3)
OTL中没有对所有者/线程数据共享的直接支持,因为我的多线程经验告诉我,这总是一件坏事。 (同意,有时它是唯一的解决方案,但仍然是一件坏事。)
你应该使用第二个mghie的建议 - 创建一个(可选的基于接口的)对象并将该对象(或其接口)传递给线程。像这样:
sharedData := TSharedData.Create;
task := CreateTask(worker).SetParameter('shared', sharedData).Run;
工人:
sharedData := Task.Param['shared'].AsObject as TSharedData;
解决问题的另一种方法是在用户按下UpdateNow按钮时向任务发送“请发送更新”消息。然后该任务将使用包含当前状态的对象进行响应。但是,如果任务执行冗长的不间断计算,则此解决方案不太合适,并且共享状态方法可以更好地工作。
答案 1 :(得分:2)
查看OTL测试23,它实现了后台文件搜索。 SetParameter()
方法用于设置搜索属性,Comm
通道用于将结果传回主线程。通信已经是线程安全的,您无需实现任何进一步的同步。
修改强>
如果您不想推送而是拉模型,那么您当然可以使用标准同步工具:具有关键部分的对象,该部分在所有访问器中用于保护数据不受并发访问的影响。该对象可以是任务对象本身,也可以是由GUI线程创建并通过(再次)调用SetParameter()
传递给任务的任何第三个对象。如果不使用对象而是使用接口指针,则会更安全,因为破坏的顺序不再重要,只有在重置对其实现的接口的最后一次引用时,才会销毁保存数据的对象。 / p>