3

这似乎是一件容易的事,我只是不知道从哪种方式开始使用 OmniThreadLibrary:

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

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

OmniThreadLibrary 如何做到这一点?

4

2 回答 2

3

OTL 中没有直接支持所有者/线程数据共享,因为我所有的多线程经验告诉我,这总是一件坏事。(同意,有时这是唯一的解决方案,但它仍然是一件坏事。)

您应该遵循第二个 mghie 的建议 - 创建一个(可选地基于接口的)对象并将该对象(或其接口)传递给线程。像这样的东西:

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

工人:

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

解决问题的另一种方法是在用户按下 UpdateNow 按钮时向任务发送“请发送更新”消息。然后,该任务将使用包含当前状态的对象进行响应。但是,如果任务执行冗长的不间断计算,则此解决方案并不真正合适,共享状态方法效果更好。

于 2011-01-11T17:33:19.117 回答
2

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

编辑:

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

于 2011-01-11T16:13:48.297 回答