用一般的方法写出的程序都是单线程的。一些常时间运算,大循环处理。都和死机一样。
现在我想做一个用ADO的带后台线程的程怎么老是出错。有什么要注意的地方大家来提点 解决了再给大家500分。

解决方案 »

  1.   

    我看一篇文章说所有的ado组件都要手工创建,也可以先建一个数据模块然后再线程中创建。可是我动态创建数据模块后,总连不上数据库。真不知怎么搞的。
      

  2.   

    呵,,先说一个吧,对于VCL控件的调用,尤其是涉及到界面的,最好在同步方法里面完成,
      

  3.   

    可以传递组件的 在Creat()中可以做的 
    线程的.AdoQuery := Form1.AdoQuery;我的这样实现了
      

  4.   

    我想在线程里连接数据库,界面操作已经同步了。
    数据模块里放了一个adoconnection组件可是在线程里open时,不能再执行下去。可在线程处手动创建一个数据模块,然后open时,能返回的。
      

  5.   

    procedure digthread.fconndb;
    var i:integer;
            begin
                if not dbm.con.Connected then
                begin
                for i:=1 to 3 do
                    begin
                             hint('尝试第'+inttostr(i)+'次连接...');//已经同步了
                            if dbm.con.Connected then break;
                            try
                                    dbm.con.Open;//到这里就不动了
                            finally
                                    ;
                            end;
                    end;
                if dbm.con.Connected then
                    hint('数据库连接成功')
                else
                    hint('数据库连接失败');
                end;
            end;
      

  6.   

    我曾经使用多线程去执行reflash,但是操作不成功!我认为也是跟显示的控件发生冲突!我感觉可以使用窗体弹出一个动态的窗体去显示你想要的结果!这样可能会好办很多!
      

  7.   

    谁有大数量,分页查询的例子,给一个看看
    [email protected]
      

  8.   

    CoInitialize( nil );凡是访问com对象都应该使用。线程的关闭时应该使用CoUnInitialize;否则ADO肯定出错,我相信肯定有不少的朋友经历过这种问题的:这两个函数极有可能是在execute()之中!!!!下面是我从网上找的一篇文章:本人最近正在进行呼叫中心的座席端和服务器软件开发,座席端登录部分是进行提取主机信息,然后使用SOCKET提交给远程服务器,服务器再在后台数据库中进行查找信息,进行对比,看是否允许座席端主机登录,因为我的电脑中无法安装SQLSERVER,所以 ,后台数据库暂时使用access小型数据库进行代替,到后期可以改为SQLSERVER数据库,,我在后台数据库中使用了两个表,使用WORKMARK字段将其相关联,如果在第一个表中查找到信息以后马上会进入第二个表中进行查找,如果第一个表中的信息符合,就返回个客户第二个表中的信息,因为座席端主机有200多台,为了防止几台主机同时进行验证信息,引起冲突,我在服务器端建立多线程,利用线程进行后台的查询,以及查找结果的回传,编写成功后进行测试,发现当一个主机连接后可以测试成功,但是,当第二个或者以后的线程产生时,数据集在第一个表中可以查到正确的信息,但是进入第二个表中时,会发现按照正确的查找条件进行查找时,查到的信息都为NIL,而且经过跟踪,发现,其实ADO已经找到了正确的信息,而且已经发送成功了,但是却无法接收到,当时我在论坛中发表了一个帖子寻求帮助,有些朋友说可能ACCESS数据库不提供多线程访问,但是我听说很多的论坛中好像都使用了ACCESS进行后台线程的查找的。翻看MSDN中关于COM的说明:发现我的线程中竟然缺少最重要的两个函数过程CoInitialize( nil );凡是访问com对象都应该使用。线程的关闭时应该使用CoUnInitialize;否则ADO肯定出错,我相信肯定有不少的朋友经历过这种问题的:
      

  9.   

    我的线程代码如下:unit Unitquerythread;interfaceuses
      windows,SysUtils,Classes, Dialogs,ADODB,db, NMMSG, ActiveX{必须要有};type
      QueryThread = class(TThread)
      private
       FComputerInfor,FIPaddressinfo: string;  //传递的信息
       FAdoQuery,FAdoQUserInfor:TadoQuery;  //动态生成的表一,表2
       
       Fadoconnection:Tadoconnection;  //动态生成的连接
       Fnmmsg,FNMretureMSG:TNMMSG;//用来发送返回信息的组件
    filestream:tfilestream;
        procedure ExtractInfor(TransInfo:string{自定义的从该提交信息中分离信息的过程});
        procedure ShellexeQuery;
      Destructor Destroy;  protected
        procedure Execute; override;
      public
    constructor  create(ComputerInfor:string;{传输来的计算机信息}IPaddressinfo:string{传输来的IP地址信息};nmmsg,NMretureMSG:TNMMSG);
      end;
    var
      ExtractDomainUser:string;  //提取出来的域用户名
      ExtractComputername:string;//提取出来的计算机名称
      ExtractDomainname:string;//提取出来的域名
      strlist:Tstringlist;
      IPlist:Tstringlist;//保存查找到的本工作组的ip地址信息
      const defeat='defeat';  //验证失败,必须注销客户机,在数据库中重新进行写入
      

  10.   

    implementation
      uses Unitsendthread;
    constructor QueryThread.create(ComputerInfor, IPaddressinfo: string;nmmsg,NMretureMSG:TNMMSG);
    begin
      CoInitialize( nil );//使用com对象必须要初始化
      inherited create(false);
      FreeOnTerminate:=true;
      FComputerInfor:=ComputerInfor;
      FIPaddressinfo:=IPaddressinfo;
      IPlist:=Tstringlist.create;//创造ip列表
      FAdoQuery:=TAdoQuery.Create(nil);     //动态生成表一
      FAdoQUserInfor:=TadoQuery.Create(nil);//动态生成表2
      Fadoconnection:=Tadoconnection.Create(nil);//动态生成的连接
      Fadoconnection.LoginPrompt :=false;
      Fadoconnection.KeepConnection :=true;
      Fadoquery.Connection:=Fadoconnection;
      FAdoQUserInfor.Connection :=Fadoconnection;
      Fadoconnection.ConnectionString :='Provider=Microsoft.Jet.OLEDB.4.0;Data Source=PersonInformation.mdb;Mode=Read;Persist Security Info=False';
      Fnmmsg:=nmmsg;
      FNMretureMSG:=NMretureMSG;
      strlist:=Tstringlist.Create;
      
    end;destructor QueryThread.Destroy;
    begin
      FAdoQuery.FREE;
      FAdoQUserInfor.FREE;
      Fadoconnection.Free;
      strlist.Free;
      iplist.free;
      CoUnInitialize;//必须使用
    inherited destroy;
    end;procedure QueryThread.Execute;
    begintry
    begin
      extractinfor(FComputerInfor);  //进行信息提取
    Synchronize(ShellexeQuery);//
    end;
    exceptself.Terminate;end;end;procedure QueryThread.ExtractInfor(TransInfo: string);//改过程进行提取用#进行分割//的串里的各个字符串integer;
    j:array [1..2]of integer;//用来保存分割符的位置
    H,L,M,N:integer;//进行组合字符串时的循环参数begin全局变量,首先清空
          ExtractDomainUser:='';
          ExtractDomainname:='';
          ExtractComputername:='';
          H:=1;//=================================
    try
        begin
             for i := 1 to length(TransInfo) do        if TransInfo[i]='#' then //找到了
               begin
                j[H]:=i;
                
                inc(H);
                continue;  //跳出循环
               end;    BEGIN
         for L:=1 to j[1]-1 do
              ExtractDomainUser:=ExtractDomainUser+TransInfo[L]; //提取的登陆域用户名
              ://showmessage(extractdomainuser);
         for M:=j[1]+1 to j[2]-1 do
              ExtractDomainname:=ExtractDomainname+TransInfo[M];//提取的域控制器名
            //showmessage(extractdomainname);
         for N:=j[2]+1 to length(trim(TransInfo)) do
              ExtractComputername:=ExtractComputername+Transinfo[N];//提取的计算机名
             //showmessage(extractcomputername);
        END;
       end;//进行异常处理
      Except
       // messagebox(0,'信息提取出现错误!','提示信息',mb_iconinformation);
      end;
    end;
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////