请问一下Thread的问题,100分奉送 当涉及对VCL控件从操作时,不应该直接将代码写在TThread的Execute方法中,因为这有可能引起线程之间的冲突。可以把代码写在一个独立的函数里,然后在Execute中用Synchronize(TThreadMethod &Method)调用该函数。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 VCL大部分都是Thread Unsaft的。 DELPHI5的VCL好像大多是ThreadSafe的,但ADO是个COM,所以不在其列,要用多线程用COM的方法(这我也不熟了^_^) 代码大致如下,在buttonClick中能正常工作,但是在execute中不能正常工作。var adoQ:TADOQuery;beginTry adoQ := TADOQuery.create……finally adoQ.freeend; TADOQuery是放在form中的,所以如果你要用的话得加上 form.TADOQuery.xxx ///////////////unit1 start///////////unit Unit1;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,ADOdb,Unit3;type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1; m_ado : Tado;implementation{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);begin m_ado := Tado.create(); m_ado.Resume ; showmessage('ado create ok')end;procedure TForm1.Button2Click(Sender: TObject);begin m_ado.Terminate; showmessage('ado free ok')end;end.//////////////////unit3 start///////////unit Unit3;interfaceuses Classes,ADOdb;type Tado = class(TThread) private { Private declarations } Fado : TADOQuery; protected procedure Execute; override; destructor Destroy; override; public constructor Create(); property ado: TADOQuery read Fado write Fado; end;implementationconstructor Tado.Create;begin inherited Create(false); Fado := TADOQuery.create(nil);end;procedure Tado.Execute;begin //...end;destructor Tado.Destroy;begin Fado := nil; inherited Destroy;end;end.//调试成动 可是当Execute中有动作的时候就S了, :(unit Unit3;interfaceuses Classes,ADOdb,Dialogs;type Tado = class(TThread) private { Private declarations } Fado : TADOQuery; protected procedure Execute; override; destructor Destroy; override; public constructor Create(); property ado: TADOQuery read Fado write Fado; end; implementationconstructor Tado.Create;begin inherited Create(false); Fado := TADOQuery.create(nil);end;procedure Tado.Execute;begin with Fado do begin ConnectionString := 'DBQ=C:\WINDOWS\DESKTOP\update\Bigrich.mdb;DefaultDir=;' + 'Driver={Microsoft Access Driver (*.mdb)};DriverId=25;' + 'FIL=MS Access;ImplicitCommitSync=Yes;MaxBufferSize=512;' + 'MaxScanRows=8;PageTimeout=5;SafeTransactions=0;Threads=3;' + 'UserCommitSync=Yes;'; sql.Clear; sql.Add('Select ID from letters'); Open; // 不open还好了,否则就蓝屏了,如果 Active := True; 也会蓝屏. end; showmessage('看见我没有,看到就OK了,看不到就蓝屏,呵呵 :)'); end;destructor Tado.Destroy;begin Fado := nil; inherited Destroy;end;end. 我看还是因为ADO或和ADO相连的DBGRID等显示控件是属于VCL的一部分,而访问VCL的只能是进程的主线程,所以你在当前线程里OPEN是不行的。可以单独写一个过程,比如:PROCEDURE AdoOpen;begin fado.open;end;然后在你刚才的线程里:Synchronize(AdoOpen);以上是我的想法,没有实践,见笑了. 今天好好的看了看帮助,发现xzisgood说的和帮助上的差不多……我再试试,完了把代码贴出来,大家一起进步一下,呵呵 :) 问题解决了。而且基本上搞清楚了TThread的用法。如果大伙有兴趣的话,可以说一声,我把TThread的详细用法写出来。 使用FastReport装载图片问题! ocx控件注册成功 但不能正常使用 散分,头100人有效! 有关DBGrid1自动添加序列号的问题 请教如何在delphi中操纵excel,望穿浑水等待中... 怎么样删除应用程序自己? 如何做2个bmp的交替闪烁? 关于窗体的问题 高分求教(在线等待) 关于使用delphi6 那里有Adobe Acrobat Reader下载? 简单问题:Tregistry.BeadBinaryData和动态数组的问题,急急急!!!!
在execute中不能正常工作。var
adoQ:TADOQuery;
begin
Try
adoQ := TADOQuery.create……
finally
adoQ.free
end;
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls,ADOdb,Unit3;type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
m_ado : Tado;
implementation{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);
begin
m_ado := Tado.create();
m_ado.Resume ;
showmessage('ado create ok')
end;procedure TForm1.Button2Click(Sender: TObject);
begin
m_ado.Terminate;
showmessage('ado free ok')
end;
end.//////////////////unit3 start///////////
unit Unit3;interfaceuses
Classes,ADOdb;type
Tado = class(TThread)
private
{ Private declarations }
Fado : TADOQuery;
protected
procedure Execute; override;
destructor Destroy; override;
public
constructor Create();
property ado: TADOQuery read Fado write Fado;
end;implementationconstructor Tado.Create;
begin
inherited Create(false);
Fado := TADOQuery.create(nil);end;procedure Tado.Execute;
begin
//...
end;destructor Tado.Destroy;
begin
Fado := nil;
inherited Destroy;end;end.
//调试成动
Classes,ADOdb,Dialogs;
type
Tado = class(TThread)
private
{ Private declarations }
Fado : TADOQuery;
protected
procedure Execute; override;
destructor Destroy; override;
public
constructor Create();
property ado: TADOQuery read Fado write Fado;
end; implementation
constructor Tado.Create;
begin
inherited Create(false);
Fado := TADOQuery.create(nil);end;procedure Tado.Execute;
begin
with Fado do begin
ConnectionString :=
'DBQ=C:\WINDOWS\DESKTOP\update\Bigrich.mdb;DefaultDir=;' +
'Driver={Microsoft Access Driver (*.mdb)};DriverId=25;' +
'FIL=MS Access;ImplicitCommitSync=Yes;MaxBufferSize=512;' +
'MaxScanRows=8;PageTimeout=5;SafeTransactions=0;Threads=3;' +
'UserCommitSync=Yes;';
sql.Clear;
sql.Add('Select ID from letters');
Open;
// 不open还好了,否则就蓝屏了,如果 Active := True; 也会蓝屏.
end;
showmessage('看见我没有,看到就OK了,看不到就蓝屏,呵呵 :)');
end;destructor Tado.Destroy;
begin
Fado := nil;
inherited Destroy;
end;
end.
PROCEDURE AdoOpen;
begin
fado.open;
end;
然后在你刚才的线程里:
Synchronize(AdoOpen);
以上是我的想法,没有实践,见笑了.
如果大伙有兴趣的话,可以说一声,我把TThread
的详细用法写出来。