我在一个单线程理用了个ADOQuery,向sql数据库插入很多数据,现在有2个问题 ,当用户点击‘停止’按钮时,如何在停止线程的同时 停止数据的插入,2,为什么程序会自动退出??

解决方案 »

  1.   

    如何在停止线程的同时,停止数据的插入在插入数据的For循环里随时检查线程的Terminated状态,如果为True,就停止插入。注意回滚事务。
      

  2.   

    就是每隔几秒创建一个单线程 ,在线程里执行对数据库的查询、插入 操作! 现在有2个问题 ,当用户点击‘停止’按钮时,如何在停止线程的同时 停止数据的插入,2,为什么程序会自动退出??  
    //==============================================================================
    procedure TClientMainFrm.tmr1Timer(Sender: TObject);
    begin
      try
        Threadbool:=True;
        XYZThread := Txyz.Create(False);
      except
        sl.Add(DateTimeToStr(Now)+'--创建线程时错误');
        sl.SaveToFile('c:\测试.txt');
      end;
    end;//==============================================================================
    procedure Txyz.displaymemo;
    var LocalSourceid,RemoteSourceId:Integer;
    begin
      //Sbool:=False;Obool:=False;
      ClientMainFrm.stat1.Panels.Items[0].Text:='正在同步...';
      ClientMainFrm.mmoRunTxt.Lines.Add('正在同步...');
      ClientMainFrm.mmoRunTxt.Clear;
      myCursor:=ClientMainFrm.Cursor;
      ClientMainFrm.Cursor:=crHourGlass;
      ClientMainFrm.tmr1.Enabled:=False;
      ClientMainFrm.btnSet.Enabled:=False;  RemoteSourceId := ClientMainFrm.myini.ReadInteger('Source','远程source',0);
      LocalSourceid  := ClientMainFrm.myini.ReadInteger('Source','本地source',0);
      Coinitialize(nil);
      case MyWay of
        0:ClientMainFrm.InstRemote(RemoteSourceId,LocalSourceid); //同步到远程
        1:ClientMainFrm.InstLocal(RemoteSourceId,LocalSourceid);  //同步到本地
        2:begin
            ClientMainFrm.mmoRunTxt.Lines.add('双向同步:');
            ClientMainFrm.mmoRunTxt.Lines.add('');
            ClientMainFrm.InstLocal(RemoteSourceId,LocalSourceid);//先执行'同步到本地‘
            ClientMainFrm.InstRemote(RemoteSourceId,LocalSourceid);//先执行'同步到远程
          end;
      end;
      CoUnInitialize;end;
    //==============================================================================
    procedure Txyz.Execute;
    begin
      while not Terminated do
      begin
        try
          displaymemo;
          ClientMainFrm.ThreadFree;
        except
          sl.Add(DateTimeToStr(Now)+'--线程错误');
          sl.SaveToFile('c:\测试.txt');
        end;
      end;
    end;
    //==============================================================================
    procedure TClientMainFrm.ThreadFree;
    begin  stat1.Panels.Items[0].Text:='';
      Cursor:=myCursor;
      tmr1.Enabled:=True;
      pb1.Position:=0;
      Sqltxt:='';
      strFields1:='';
      strFields2:='';
      strFields3:='';
      strFields4:='';
      Threadbool:=False;
      XYZThread.Terminate;
      qry1.Close;
      qry2.Close;
      XYZThread.WaitFor;
      XYZThread.Free;
      XYZThread:=nil;
    end;
    //==============================================================================
    procedure TClientMainFrm.btn3Click(Sender: TObject);//停止按钮
    begin
      if Threadbool then ThreadFree;
      cltrycnTrayIcon.Hint:='数据同步器';
      stat1.Panels.Items[0].Text:='';
      if tmr1.Enabled then tmr1.Enabled:=False;
      if btnStart.Caption<>'开始' then btnStart.Caption:='开始';
      btnSet.Enabled:=True;
    end;
    //==============================================================================
      

  3.   

    存在几个问题:
    1、分线程用到主线程的对象,需要同步,用Synchronize进行同步,否则可能会出现对象访问异常。
    2、线程里需要 sleep,便于线程退出,否则一个循环里,主线程如何让分线程退出?
    3、线程启动,用不着用定时器。
    建议去看一下多线程编程一些资料,然后再写代码。
      

  4.   

    我这里只有一个线程啊? 在那里用sleep?不用定时器如何启动线程?
      

  5.   

    线程sleep主要是避免线程占用太多时间片,和线程退出没关系。如果在线程的循环里想随时退出,关键还是没循环一次就判断一次Terminated属性。否则即使你sleep(10000),在线程循环里,你也不能在主线程让子线程马上退出的。
      

  6.   

    代码如下:如果我要在10秒钟之内,要 XYZThread.Terminate; 窗体就没有反映了,如何处理??
    procedure Txyz.Execute;
    begin
      while not Terminated do
      begin
        try
          Sleep(10000);//休眠10秒钟
          DisplayMemo;
        except
          sl.Add(DateTimeToStr(Now)+'--线程错误');
          sl.SaveToFile('c:\测试.txt');
        end;
      end;
    end;
      

  7.   

    执行到displaymemo了,就要等它执行完了才能退出的
      

  8.   

    如果我要在10秒钟之内,要 XYZThread.Terminate; 窗体就没有反映了,如何处理?? 
      

  9.   

    那是因为Terminate只是设置标记位Terminated为True,并不会真正结束线程。怎么随时退出线程,再好好领会下我6楼的那句话。
      

  10.   

    如何让一个线程在06:00和00:00之间不停的运行??
    procedure Txyz.Execute; 
    begin 
      while not Terminated do 
      begin 
        try 
         Sleep(1000);//休眠1秒钟 
          DisplayMemo; 
        except 
          sl.Add(DateTimeToStr(Now)+'--线程错误'); 
          sl.SaveToFile('c:\测试.txt'); 
        end; 
      end; 
    end;
    但运行1小时候后就没有反映了。