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

时间:2011-01-11 15:51:51

标签: multithreading delphi omnithreadlibrary

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

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

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

如何使用OmniThreadLibrary完成这项工作?

2 个答案:

答案 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>