当涉及对VCL控件从操作时,不应该直接将代码写在TThread的Execute方法中,因为这有可能引起线程之间的冲突。可以把代码写在一个独立的函数里,然后在Execute中用Synchronize(TThreadMethod &Method)调用该函数。

解决方案 »

  1.   

    VCL大部分都是Thread Unsaft的。
      

  2.   

    DELPHI5的VCL好像大多是ThreadSafe的,但ADO是个COM,所以不在其列,要用多线程用COM的方法(这我也不熟了^_^)
      

  3.   

    代码大致如下,在buttonClick中能正常工作,但是
    在execute中不能正常工作。var 
     adoQ:TADOQuery;
    begin
    Try
     adoQ := TADOQuery.create……
    finally
     adoQ.free
    end;
      

  4.   

    TADOQuery是放在form中的,所以如果你要用的话得加上 form.TADOQuery.xxx
      

  5.   

    ///////////////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.
    //调试成动
      

  6.   

    可是当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;  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.
      

  7.   

    我看还是因为ADO或和ADO相连的DBGRID等显示控件是属于VCL的一部分,而访问VCL的只能是进程的主线程,所以你在当前线程里OPEN是不行的。可以单独写一个过程,比如:
    PROCEDURE AdoOpen;
    begin
        fado.open;
    end;
    然后在你刚才的线程里:
    Synchronize(AdoOpen);
    以上是我的想法,没有实践,见笑了.
      

  8.   

    今天好好的看了看帮助,发现xzisgood说的和帮助上的差不多……我再试试,完了把代码贴出来,大家一起进步一下,呵呵     :)
      

  9.   

    问题解决了。而且基本上搞清楚了TThread的用法。
    如果大伙有兴趣的话,可以说一声,我把TThread
    的详细用法写出来。