多线程查询后续问题:如何立即终止正在查询的线程?

xingzhou 2003-03-11 12:06:50
帖子http://expert.csdn.net/Expert/topic/1492/1492778.xml解决了用线程查询的问题,但是新问题又来了,用什么方法中断正在查询的线程呢?
用Terminate方法是不行的,他仅仅设置了一个标志,如果直接delete查询的线程,也不行,报“Systemc Error:code 5 拒绝访问”错。
希望各位能探讨一下。
...全文
481 53 打赏 收藏 转发到动态 举报
写回复
用AI写文章
53 条回复
切换为时间正序
请发表友善的回复…
发表回复
Spectrum 2003-04-13
  • 打赏
  • 举报
回复
学习,各位星星老大。
snake_eye 2003-04-11
  • 打赏
  • 举报
回复
红星大战!
BlueTrees 2003-03-15
  • 打赏
  • 举报
回复
补充:SocketConnection是多线程安全的,就是多个线程可以同时调用他的方法,简单的说,就是可以在不同的线程中对TClientDataSet操作,这是安全的,但是,SocketConnection通过消息机制,把不同线程的操作进行了串列化,使用多线程等同于单线程,但是,主线程有机会初始化他的界面。我不太清楚DataSource是否多线程安全,VCL界面元件原则上是多线程安全的,应该没有问题,但是困难的是在于TClientDataSet打开的时候存在主从关系,LookUp字段等等,这时候存在数据产生需要同步的问题,有些数据需要先取得,有些需要后取得。用多线程,这是比较困难的。
Wally_wu 2003-03-15
  • 打赏
  • 举报
回复
应该不太可能呀,检查清楚点呀!
BlueTrees 2003-03-15
  • 打赏
  • 举报
回复
终止一个查询线程,最简单的就是终止他使用的连接,他就会立刻出错返回,并且退出。
BlueTrees 2003-03-15
  • 打赏
  • 举报
回复
Midas使用SocketConnection的过程解释:

SocketConnection实际上在客户端生成了一个支持IDispatch接口的代理,这个代理对象实现了通过Socket调用远程服务器上面的过程,实际上,就是它实现了一个Invok的方法,他会通过Socket发送Invok的参数给服务器程序,然后一直等待服务器的返回数据。这个过程是同步的,因为如果异步的话,就需要服务器返回结果的时候指出是给哪一个Ivoke的,这是有困难的,除非增加额外的数据指出是那一个Invok,还需要使用缓存来缓存返回结果,这些做起来都是比较困难的。

实际上简单的方法就是使用多个SocketConnection,来实现异步调用,这是最简单的方法,也不会增加太多的开销。通过我对服务器程序(SckSrv)的研究,我知道,一个连接,服务器端都会增加一个线程为这个连接服务。因此和实现一个SocketConnection的异步调用是等价的。

在服务器端的ADOConnection使用异步调用也是无理的,
1、任何调用在进入同一个com的时候,都会进入临界区,其他线程都被阻塞,实际上是不允许他们同时进入同一个Com的。
2、ADOConnection异步调用,实际上你也不可能立刻返回,这时候也不允许其他线程进入这个Com,因为ADOConnection这时候是存在状态的,如果你立刻退出临界区,那么其他线程进入,就会破坏你先前的调用。这样使用异步调用毫无意义。

最好的解决办法,就是用多个SocketConnection。
copy_paste 2003-03-12
  • 打赏
  • 举报
回复
这两天忙,呵,:)
回头再看看时,都不知俺上面说些什么了。。。
xingzhou 2003-03-12
  • 打赏
  • 举报
回复
另外一个问题:http://expert.csdn.net/Expert/topic/1522/1522866.xml,
ADOStoreProc无法调用参数类型为text的存储过程
leapmars 2003-03-12
  • 打赏
  • 举报
回复
多层结构中,使用ADO的异步方式,可以终止中间层和数据层的通讯。 但是如果中间层从数据层获取的记录多达几万条,在客户端只通过 ClientDataSet.Open 来获取数据的情况下,想终止这个操作是不可能的! 因为获取这几万条记录的操作实际上是由 IAppServer.AS_GetRecords() 这一个方法完成的。 这个远程调用是最耗时的(特别是当要下载的纪录有很多的时候)。 那么,如何终止这个远程调用呢?我想不出办法。 但是如果想放弃正在执行的查询操作,倒还是可以。这就是采用MIDAS的少量多次获取数据的方法,用一个循环在每次获取少量数据后,就检测是否要终止操作! 检测的所采用的方法上面各位高人都说得很多了!^_^
猛禽 2003-03-12
  • 打赏
  • 举报
回复
具体原因见TThread的WaitFor函数的源码。

TThread在Destroy时调用WaitFor去等待当前线程结束(其中还包括与其它线程通信,以防死锁的一些东东),直接Free线程,就会等待,如果用API去终止再来FREE,因为它的HANDLE已经无效,WaitFor时又会出错。
只能不用TThread了:<
猛禽 2003-03-12
  • 打赏
  • 举报
回复
最好按正常的做法,在一次查询做完后再终止线程,即用Terminate方法。
否则:
三、在三层的客户端即使终止了客户端的查询也没有用,中间层仍在占用资源进行查询,而且如果强行终止客户端线程还可能会导致中间层出错,或scktsrvr等代理程序出错。

若真的要强行终止线程,也不要用API来做:
一、不要用API去终止线程,它是会造成MEMORY LEAK的,因为它不会同时FREE线程对象。

建议做法:
不要用TThread类,用RTL的BeginThread来实现
xingzhou 2003-03-12
  • 打赏
  • 举报
回复
但是,这些都是线程之间的通讯问题,请注意了,本贴的标题是:如何立即终止正在查询的线程?如何有效地放弃正在执行的查询操作?
xingzhou 2003-03-12
  • 打赏
  • 举报
回复
to Raptor(猛禽):
谢谢,试试先……
猛禽 2003-03-12
  • 打赏
  • 举报
回复
TMyThread = class(TThread)
private
FMyEvent : TEvent;
// other info
public
property MyEvent: TEvent read FMyEvent;
// other info/methods
end;

procedure TMyThread.Execute;
begin
While Not Terminated Do
Begin
If ( FMyEvent.WaitFor( $FFFFFFFF ) = wrSinaled ) Then // 线程会在这里挂起,不占用资源,直到MyEvent被Set
// do something
Else
Terminate;
End;
End;


MainForm:
...
// Set info
MyThread.MyEvent.Set;
MyThread.MyEvent.Reset;
// 上两句等效于Pulse一下,然后线程就开始一次查询,查完线程就挂住了
end;
xingzhou 2003-03-12
  • 打赏
  • 举报
回复
to Raptor(猛禽):
能否给个小的示例
rwdx 2003-03-11
  • 打赏
  • 举报
回复
gz
xingzhou 2003-03-11
  • 打赏
  • 举报
回复
请先看http://expert.csdn.net/Expert/topic/1492/1492778.xml帖子,我是客户端的查询线程,这里只能用TClientDataSet,好像它没有异步方式。
我的程序框架是两个线程,主线程是界面,查询线程负责查询,查询完成后通过同步后在主界面显示结果。但是查询线程无法即时终止查询操作。
copy_paste 2003-03-11
  • 打赏
  • 举报
回复
procedure TForm1.ADOQuery1FetchProgress(DataSet: TCustomADODataSet;
Progress, MaxProgress: Integer; var EventStatus: TEventStatus);
begin

end;

你是说将EventStatus变成esCancel就行了???

我以前试过,因为数据量比较大,试了一下做成异步,但后来发现Progess, MaxProgress都不太正确,而且好像那么对应的事件也不太确定,就弃之了。。。。
copy_paste 2003-03-11
  • 打赏
  • 举报
回复
耙子,你有异步方式的,比较完整的代码没?

我看DEMO中的例子。。。。没怎么看。。。。

有没?
耙子 2003-03-11
  • 打赏
  • 举报
回复
想中止查询,只能用ADO的异步方式进行查询。即使不用额外的线程也没问题,它属于立即返回型调用,你需要主动询问查询是否结束,你可以在查询没有结束前中止查询。
加载更多回复(32)

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧