(底分100)大侠看过来:用线程执行数据库查询,挂起(中断)后再次执行查询,如何解决报的这个错??(100分)

  • 主题发起人 主题发起人 孟雯
  • 开始时间 开始时间
加一个Session如何?
 
1):jiangyiquan
如能得到您的答案将非常高兴。
我的信箱 :<a href="mailto:anywin@sina.com">anywin@sina.com</a>
我确实是第一次使用线程编程,见笑了。
2):kens
可以麻烦您把代码帖出来吗?
3):tanxh
我已经有SESSION了啊。
 
to all:
我觉得线程不能从根本上解决这个问题。
 
孟雯先生:
终于上来了,不用发E-Mail了。
依我看,问题可能出在这里:(1)你在‘挂起’时,调用的方法
不对。从你的程序中,可以看出,你想在线程挂起后释放线程对象,
但你用的办法并不能释放线程对象,你可以看一下调试时的Thread
窗口。可以用以下方法:
Windows.TerminateThread(MyThread.Handle, 0);
MyThread.Free;
但由于使用TerminateThread是一种‘野蛮’的方法,在线程
中创建的对象你必须自己释放。
另外,线程的结束和线程的挂起是两个不同的概念。Delphi中
线程的Free方法,必须在线程结束后(即从Execute方法中退出)
才能调用成功,否则易引起混乱。
TThread和线程有联系,又有区别。
(2)两次调用MyThread := TDBQueryThread.Create(...)创建
的是两个不同的线程,他们之间也应使用同步,最好使用同步对象,
不要用Synchronize(...)。
由以上可知,出现你的错误是由于两个线程共用一个Session所致,
如果你想让两个同样的线程同时运行,他们各自必须有自己的Session,
否则,出现你的问题就不足为怪了。
(3)Query.Close方法的调用,应该在Destroy方法调用。
 
>> :jiangyiquan
其他的我还没有试:
关于(2),我:
a: Synchronize(...) 是为了访问主线程的VCL资源,比如处理查询结果。
b: 中断 前 后 创建的线程是一个,所用的 Query 是一个,在 同一时间并没有两个查询
线程共存,和谁同步呢?
c: 如果我中断(挂起)n 次,创建 n+1 个线程,那要用 n+1 个 Session 吗?
请指教,非常感谢。
 
<<jiangyiquan
TerminateThread是强制把线程终止掉,太粗暴了,它不管线程使用的资源是否释放的。
很容易造成线程被终止而资源没释放。无论是微软还是宝蓝都不提倡的。
Session 是本来就是对数据库会话进行管理的,它起到了同步和阻塞的功能,当然可以对多线程用了。
《〈孟雯
我觉得在线程中要实现这样的功能我现在还没想到。要中断的时候直接把与数据库的连接断了,他要再查询时再连上行不行。
我在封装DBLIBRARY连接SQLSERVER时考虑过类似的问题。可以帮你想想了
呵呵想不出来也没办法了我比较菜呵呵。
 
你可以这样试试:
所有的数据库控件都在线程里动态创建,当线程结束时释放,这样就不会有上面出现的问题了。
但这样存在另外一个问题,可能就是称为“内存泄露”的问题了,我现在的程序就存在这样的问题,程序运行时虚拟内存不断上涨,无法控制。
 
你要让ORACLE停止查询,DELPHI没有线程办法:BDE不支持。只能用OCI调用。
 
你的session、db等等,根本就是在主线程创建的
 
Delphi 的whitepaper明确说过,database控件是线程不安全控件,如果你做
类似Codeinside的功能,应该用多进程,我们team原来做过一次,感觉不是很好
也是线程老出错,后来用多进程的方法就没事了。
 
>>各位大虾
可以把代码贴一下吗?
 
jiangyiquan的回答中关于TSession的那一条是最重要的。你的多个线程使用的是同一个
Session,所以你若执行完一个数据库会话(线程执行完毕)后Session可以再被其他线程
使用,但若只是挂起你的线程的话,该Session并没有结束,所以会有你所遇到的错误。
建议你看一下以前已被解答的问题,里面有比较详细的解答。
 
只能绕道解决。我也碰到该问题,我的做法是在查询数据库前,自己判断上次查询后
数据库是否关闭。若没有关闭则挂起线程,用一个Timer周期查询等待直到上一个查询
退出才resume线程。
 
应该创建线程自己的Query、Database 、DataSource和DbGrid
而不要从外部传变量
 
孟雯 上次进入: 01-1-30 15:32:17
 
后退
顶部