数据库多线程查询的问题

        生成报表时,查询的时间很长,客户希望能够提供查询进度条的显示功能。一开始我决定使用ADO自身的异步执行功能,但发现这种方式只对SELECT类型的查询有用,而且不支持存储过程。即使是SELECT类型的查询,使用时也非常的不稳定,经常报错。于是决定放弃这种方式,改用多线程来解决。

        因为不可能在程序中直接知道报表查询的进度, 因此我决定在存储过程中将进度信息写入一张表中,程序再访问这张表来知道当前查询执行的进度。为了减少程序的改动量,我建了一个新的线程来访问查询进度信息表,并将这些信息在界面上显示出来,这样就基本上不需要改动原来的查询代码。但试了N多遍都发现没有效果,新建立的线程始终只能在报表查询执行完毕后才会去执行,而不能在报表查询进行的同时执行访问查询进度信息表的任务。这让我很困惑,试了许久才发现,必须把报表查询放在新开的线程中,而把显示进度信息的查询放在主线程中执行,这样两种查询才会同步执行。不是太明白为什么会这样,大概是因为主线程的执行优先级更高一些吧,在主线程中执行长时间的查询操作会占大量的CPU利用率,而使得其它低级别的线程没有执行的机会。把进度查询放在主线程后,因为这种查询虽然执行的次数很多,每半秒一次,但因为每次执行的时间很短,不会占用大量CPU使用率,所以就不会阻塞其它线程的执行。不过只是猜测而且,真正的原因不清楚。

      另外,要取消了一个未完成的线程查询的话可以使用Dataset.Recordset.Cancel方法,如果直接调用Terminate来结束线程的话,并不能取消已经提交给数据库的查询操作,ADO会报错。

        还有一个问题就是我设置了OnTerminate事件,在线程执行完毕后调用FastReport报表显示控件,如果用户查询执行当中直接把窗体关了,即使我在窗体关闭前Cancel掉这个查询,程序也会报错,但如果没有指定OnTerminate事件就不会报错,从报错情况来看应该是OnTerminate中代码出现的内存访问错误(访问了窗体上的控件),但奇怪的是难道在线程结束之前窗体对象就已经释放了吗?

       最后的解决的方法是在窗体的关闭事件中先将线程的OnTerminate指向Nil,再Cancel掉这个查询。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值