我希望能够在自己的线程中异步打开TDataSet,以便主VCL线程可以继续,直到完成,然后从该TDataSet读取主VCL线程。我做了一些实验并且遇到了一些非常奇怪的情况,所以我想知道是否有人这样做过。
我见过一些示例应用程序,其中TDataSet是在一个单独的线程中创建的,它是打开的,然后从中读取数据,但这都是在单独的线程中完成的。我想知道在另一个线程打开数据源之后从主VCL线程读取TDataSet是否安全。
我在Delphi 7中进行Win32编程,使用DAC for MySQL中的TmySQLQuery作为我的TDataSet后代。
答案 0 :(得分:5)
如果您只想在自己的线程中使用数据集,您可以使用synchronize与主线程进行通信以进行任何VCL / UI更新,例如与任何其他组件一样。
或者,更好的是,您可以使用自己的消息传递系统实现mainthread和worker线程之间的通信。
检查Hallvard的螺纹解决方案:
http://hallvards.blogspot.com/2008/03/tdm6-knitting-your-own-threads.html
或另一个:
http://dn.codegear.com/article/22411
有关同步及其低效率的一些解释:
http://www.eonclash.com/Tutorials/Multithreading/MartinHarvey1.1/Ch3.html
答案 1 :(得分:3)
我已经看到它与TDataSet的其他实现一起完成,即在Asta组件中。这些将与服务器联系,立即返回,然后在加载数据后触发事件。
但是,我认为这在很大程度上取决于组件。例如,那些相同的Asta组件无法以主VCL线程以外的任何方式以同步方式打开。
简而言之,我不认为这是TDataSet本身的限制,而是特定于实现的内容,而且我无法访问您提到的组件。
答案 2 :(得分:3)
在多个线程之间使用相同的 TDataSet 时要记住的一件事是,您只能在任何给定时间读取当前记录。因此,如果您正在一个线程中读取记录,然后另一个线程调用下一步,那么您就遇到了麻烦。
答案 3 :(得分:2)
还记得线程很可能需要自己的数据库连接。我相信这里需要的是一个多线程“保持”对象,用于将数据从线程加载到(只写),然后只从主VCL线程读取。在阅读之前使用某种同步方法来确保您不会在同一时刻阅读您的书写,或者在同一时刻阅读您的阅读,或者将所有内容加载到内存文件中并编写同步方法以告诉主应用程序在文件中的位置停止阅读。
我已经采用了最后一种方法,省略了预期记录的数量(以及数据集的大小),我甚至将其用于本地系统上的物理磁盘文件。它运作得很好。
答案 4 :(得分:1)
我已经完成了多线程数据访问,并不简单:
1)您需要为每个线程创建一个会话。
2)对该TDataSet实例所做的一切必须在创建它的线程的上下文中完成。如果你想放置,例如,这并不容易它上面有一个数据库网格。
3)如果你想让...主线程与您的数据一起使用,直接的解决方案是将其移动到某种单独的容器中,例如。内存数据集。
4)一旦数据检索完成,您需要某种信令机制来通知主线程。
......并且异常处理不是直截了当的......
但是:一旦你成功了,应用程序将非常优雅!
答案 5 :(得分:0)
大多数TDatasets都不是线程安全的。我知道线程安全的是kbmMemtable。它还能够克隆数据集,以便确实发生移动记录指针的问题(正如Jim McKeeth所解释的那样)。它们是您可以获得(购买或免费)的最佳数据集之一。