线程怎么安全退出? (100分)

  • 主题发起人 没理头号
  • 开始时间

没理头号

Unregistered / Unconfirmed
GUEST, unregistred user!
线程怎么安全退出?
我有一个线程
constructor TReadDSThread.Create;
begin
FreeOnTerminate := true;
//线程自动销毁
inherited Create(false);
//继承构造函数
end;
procedure TReadDSThread.Execute;
var
fQuery: TQuery;
fSQLStr: string;
fDataSet: TDatabase;
fSession: TSession;
begin
//这里一大堆代码是为了线程安全,这样做对吗?有别的什么办法吗?
fSession := TSession.Create(Application);
fSession.SessionName := '1';
fDataSet := TDatabase.Create(application);
fDataSet.SessionName := fSession.SessionName;
fDataSet.LoginPrompt := false;
fDataSet.Params.Add('user name=' + AUser);
fDataSet.Params.Add('password=' + APass);
fDataSet.AliasName := ADataName;
fDataSet.DatabaseName := '2';
fDataSet.Connected := true;
fQuery := TQuery.Create(Application);
fQuery.DatabaseName := fDataSet.DatabaseName;
fQuery.SessionName := fDataSet.SessionName;
try
while (not Terminated) do
begin
....
fQuery.Close;
fQuery.SQL.Clear;
fQuery.SQL.Add(fSQLStr);
fQuery.ExecSQL;//当线程强行Terminated时,这里会出错,这里怎么处理啊?
...
end;
finally
fQuery.Free;
fDataSet.Free;
fSession.Free;

end;
end;
 
我跟踪了一下,好象是我在FormClose里用
DThread.Terminate;
//结束线程,
可在FormDestory执行后,线程好象仍在执行,
难道不是这样结速线程吗?
 
你线程退出的方法是正确的,估计是fQuery的问题
 
楼上的,fQuery也就是执行了一句sql语句啊?
不过我用的是bulk insert导大批量的数据,
所以时间会很长!
 
没人知道吗?
在线等待啊!
解决再加200分给你!
 
你试试把Execute中的内容写在同步中。
 
to :子弹
没用,我试过了,老样!
 
我估计是执行SQL语句不有完成旱,结束线程时引起的错误,你试的装一下,delphi的ADO补丁
 
to fhqkhnzh:
我用的是bde啊?
不过我连数据是用odbc
 
我换用bde直接连还是不行,tnnd,不爽
 
你应该先将 fQuery、fDataSet、fSession给close掉,然后在FreeAndNil
 
C:/Program Files/Borland/Delphi6/Demos/Db/IBX/ThreadedIBX
参考一下这个怎么样
 
to :ugvanxk
我看了,没什么用?
我听人说对于query的查询,bde会在主线程外另开一个线程执行查询,也就是主线程退出,
查询还在进行,这时退出就会出错?
我查了以前的帖子,好象这个问提一直没解决,
有谁解决了说出来听听!
 
我知道为什么了,
因为用Terminate方法好象只是把Terminated设成true而已,
并没有马上结束线程,
因为我线程执行过程这样的
while not Terminated do
begin
for i:=0 to 1000 do
begin
...
//do something
...
end;
end;

好比假如当Terminated变成true时,do something仍在执行
这时窗体的很多东西都在释放,这样的话,do something就会出错,
但看了TThread的帮助,好象没有什么立即结束线程并释放内存的方法,
是不是还有什么别的方法?
注:
我现在的解决方法是在
for i:=0 to 1000 do
begin
if(Terminated)then
break;//解决
...
//do something
...
end;
但这样好象不是很好,如有嵌套for就很麻烦,有没有老大有好方法啊?
 
在Terminated之前先调用
TerminateThread( Thread.Handle, 0 );
 
楼上的老大,TerminateThread不会释放线程资源,这样机器都会被你搞死!
 
所以在TerminateThread之后再调用线程的Terminated
 
但我有个疑问了,
TerminateThread都把线程结束了,
线程还怎么自己去释放一些它生成的变量啊?

 
你试过了吗?
 
你说过TerminateThread不会释放线程资源的
 
顶部