一个线程查询类的使用,大家看看怎么回事!(20分)

  • 主题发起人 主题发起人 网事如风
  • 开始时间 开始时间

网事如风

Unregistered / Unconfirmed
GUEST, unregistred user!
//多线程类申明!
TAdoSD_Thread = class(TThread)
private
FSQLString : string;
FADOQuery : TADOQuery;
FStringGrd : TbsskinStringGrid;
FLabel : TLabel;
protected
procedure Execute;
override;
public
constructor Create(ADO:TADOQuery;
SGRD:TbsskinStringGrid;
S: String;Lab: TLabel);
overload;
procedure SQLtoStringGrid;
end;

//线程类TAdoSD_Thread的实现:
constructor TAdoSD_Thread.Create(ADO: TADOQuery;
SGrd:TbsskinStringGrid;
S: String;Lab: TLabel);
begin
FADOQuery := ADO;
FStringGrd := SGrd ;
FSQLString := S;
FLabel := Lab;
inherited Create(False);
end;

procedure TAdoSD_Thread.Execute;
begin
FreeOnTerminate:=True;
Synchronize(SQLtoStringGrid);
if Terminated then
exit;
end;
procedure TAdoSD_Thread.SQLtoStringGrid;
var
i,j : integer;
begin
if FADOQuery<>nil then
begin
FADOQuery.Close;
FADOQuery.SQL.Text := FSQLString;
FADOQuery.Open;
end;
if FADOQuery.RecordCount < 1 then
Exit;
NowRowCou := FStringGrd.RowCount - 1;
FStringGrd.RowCount := NowRowCou + FADOQuery.RecordCount + 1;
if FADOQuery.Eof = false then
begin
for i := 1 to FADOQuery.RecordCountdo
begin
FStringGrd.Cells[ 0,NowRowCou + i] := inttostr(NowRowCou + i);
for j := 1 to 18 do
FStringGrd.Cells[ j,NowRowCou + i] :=
FADOQuery.Fields.Field[j-1].AsString;
FADOQuery.Next;
end;
end
else
FADOQuery.Close;
end;
//多线程类的调用:
调用时的语句如下:
AdoSD_Thread := TAdoSD_Thread.Create(DM.ADOQry_CX, SBcx_Grd,string_sql,Label1);
AdoSD_Thread.Execute;
那么会执行两次SQLtoStringGrid中代码,如果注释掉AdoSD_Thread.Execute;则是所要结果。
AdoSD_Thread := TAdoSD_Thread.Create(DM.ADOQry_CX,SBcx_Grd,string_sql,Label1);
什么都没做啊!
可事实是它执行了SQLtoStringGrid中的代码,高手给解释下,谢谢!

 
你这样做的结果根不使用线程的效果是一样的,Synchronize方法就是要求其调用的方法到主线程执行,而你把整个查询过程都放在了SQLtoStringGrid过程中,这个过程应尽可能的简断。你应该在create中再传过来一个datasource控件,把SQLtoStringGrid的过程都入在execute方法中,然后在在SQLtoStringGrid中写进行datasource与dbgrid的连接操作
 
TO:桦树皮
"Synchronize方法就是要求其调用的方法到主线程执行"怎么解,
请赐教,
另外我的查询数据多时有百十万,所以用到了线程,不过线程中数据取的不多,
是在ScrollbarChange中执行的,是一个循环类加的过程,这个过程执行很短,所以
无所谓的放那的。
我只是想知道为何SQLtoStringGrid会在Create中执行呢?
线程执行不是在EXECL中吗?再次我的create中并没有调用SQLtoStringGrid,
可它偏执行了,很是费解,希望指点!
分不是问题,可以另给的!
谢谢!
 
线程的Execute方法是不需要显示调用的。看看你的create中:inherited Create(False);
这样线程创建之后会直接执行(调用Execute方法)的。
 
"Synchronize方法就是要求其调用的方法到主线程执行"怎么解,
请赐教,
-----------------------------------------------
赐教不敢当
Synchronize方法是把调用的方法切换到主线程执行,因为你建立的线程没有消息循环,所以为了与VCL进行沟通,就通过Synchronize方法,让其线程与主线程同步,利用主线程的消息循环把查询的结果传递给VCL的数据感知控件,如果你把整个查询的过程都放在Synchronize中,结果跟在主线程中查询是一样的。
------------------------------------------------------------

我只是想知道为何SQLtoStringGrid会在Create中执行呢?
线程执行不是在EXECL中吗?再次我的create中并没有调用SQLtoStringGrid,
可它偏执行了,很是费解,希望指点!
分不是问题,可以另给的!
谢谢!
---------------------------------------------
至于这个问题你还是找本基础的书看看吧,因为你根本没理解线程的运作方式。
 
呵呵,桦树皮老兄,无意冒犯!
昨天干了一个通宵,本来下午想早点回去的,可出了这个问题,
急着回去,所以言语可能有点不当,望见谅!
不胜感激!
回头补过Thread这一课!多谢多谢!
 
不用客气,共同提高嘛。:)
 
小弟刚学D不久,前一段的一个项目刚好用到线程,喊两嗓子不知对不对:TAdoSD_Thread.Create(DM.ADOQry_CX, SBcx_Grd,string_sql,Label1);
这句话就是调用线程并执行(默认是False),然后你又AdoSD_Thread.Execute,当然是执行两次了。
“ 线程执行不是在EXECL中吗?”是在execute中执行,但是指线程的的执行过程!!你要掉用线程,线程会自己执行Execute的,就不用你在专门调用了。所以只要TAdoSD_Thread.Create(DM.ADOQry_CX, SBcx_Grd,string_sql,Label1);就可一了。
喊两嗓子就是爽。
 
多谢各位,尤其是桦树皮老兄,理清了我在线程上的思维错误,
这几天猛研究了一通,诚如各位所言,多谢多谢! 结贴!
 
AdoSD_Thread.Execute;
//Needn't call, Execute is auto called
 
多人接受答案了。
 
后退
顶部