如何让一段要执行很长时间的循环交出控制权(类似C#,VB的DOEVENTS)?
用线程能实现吗?

解决方案 »

  1.   

    while 条件 do
    begin
      ...
      ...
      Applicaton.ProcessMessage;
    end;================================================================
         ◆◆◆ CSDN查询助手,查询方便快捷 ◆◆◆ 下载地址:  
     http://CoolSlob.ifood1.com/Download/CSDNFinder.exe  
     http://CoolSlob.8u8.com/Download/Tools/CSDNFinder.Slob[更名为.exe即可]  
      

  2.   

    举个例子,说明一下(此例是引用别人的例子,具体作者就不记不得了)  当一段程序代码在执行一个很费时的操作(例如对软盘进行读写操作)时,其他控件将无法得到Windows的消息,换句话说,将一个过程被执行时,在该过程结束之前,应用程序的回调函数不会被Windows调用,也就无法响应系统消息。
      举例来说,如果在一个过程中改变了一个TLabel控件的Caption属性值,仅当该过程结束后用户才会在屏幕上看到TLabel控件被重画,如果你设计了一个拷贝文件的过程,并想在拷贝过程中不断地显示已拷贝的字节数,如果直接在拷贝操作的循环中改变要显示的字节数是不行的,用户实际上看不到这个不断变化的数字,因为当拷贝操作的过程未结束之前,其它控件根本未接收到重画消息。  另一个极端的例子,如果你的程序要进行一个死循环,退出该死循环的条件是用户单击按钮Button2,那么你会发现在死循环执行期间,所有的控件都失效了,你的程序也就变成了一个大BUG。下面的代码示例显示了如何避免这一问题,该段程序的含义是当用户单击按钮Button1时开始执行死循环,单击Button2时退出这个死循环。var
      ExitFlag: Boolean = false;procedure TForm1.Button1Click(Sender: TObject);
    const
      Busy: Boolean=false;
    begin
      if Busy then Exit; // 若已进入本过程则退出
      Busy := true; //设立已进入本过程标志,这一句很重要
      while true do begin    Application.ProcessMessages; // 让其他控件能获取消息
        if ExitFlag then Break; // 若标志为真退出死循环
      end;
      Busy := false; // 清除已进入本过程标志
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      ExitFlag := true;
    end;
       上例中有两点很重要,其一是死循环中的Application.ProcessMessage,这句代码使程序的其他控件也能获取消息,如果没有这一句则程序会陷入死循环中;另一个重要的代码是在Button1Click过程开始处判断是否正在执行死循环,若是则直接退出,如果没有这个判断,则当用户重复单击Button1时可能导致代码重入,因为在过程中调用了ProcessMessage方法。
      

  3.   

    CoolSlob() 的这个方法就不错了嘛,何必那么麻烦呢?
    while YesOrNo do  //执行循环
    begin
      ...
      ...
      Applicaton.ProcessMessage;
    end;///当你要停止这个循环时,只需要YesOrNo:=False;
      

  4.   

    要分情况而论,可以用Applicaton.ProcessMessage;
    但这要求你在每次用到它的时候的占有时间短要小,
    如果要很长时间,就只有用thread了,没有什么别的好的办法!