0

我必须处理一个很长的数据库表,并想出中止此循环的最常见方法。主要代码序列是这样的

 procedure TForm.ProcessmyTable(Sender : TObject);
 begin
 ..... 

 myTable.first;

 repeat
  ReadSingleRecordfromTable ( MyTable, aRecord) ;
  ProcessMyRecord(aRecord) ;
  MyTable.next;
 until MYTable.EOF;

 end;


 unit ....   ;

 procedure  ProcessMyRecord(aRecord : TMyDataRecord) ;
 begin

     //   do not have user interface stuff here
     //   Application.Processmessages  will not work here  !!!


     ....  ( long running code sequence) 

 end;

可以做一个计时器并根据计时器打破循环,并以 var 作为标志支持....但这真的是解决这个问题的最聪明的方法吗?

4

3 回答 3

1

如果此代码在主线程中运行,那么Application.ProcessMessages如果您希望用户与您的程序交互并中止,您将需要为消息队列提供服务(即 call )。在这种情况下,我认为您已经知道解决方案。打电话Application.ProcessMessages。如果用户选择中止,请设置一个布尔标志并在最内层循环中定期检查该标志。

当然,这一切都相当混乱。根本问题是您在 GUI 线程上执行长时间运行的操作。那是你不应该做的事情。将数据库处理代码移到不同的线程上。如果用户选择中止,则向线程发出要中止的信号。例如,调用Terminate线程的方法将是执行此操作的一种方法。

于 2013-04-24T10:26:27.823 回答
0

如果这是一个漫长的过程,用户可能希望在 Windows 应用程序中确定中止,则应该与 GUI 进行一些交互,完成记录计数或进度条(如果不是在每条记录上,则定期进行)任何调用更新标签或进度条将提供设置中止标志的机会(因此不需要 processmessages)。另外,如果用户可以看到一些进展,他们可能不太可能在无聊时中止但完成了 95%。

恕我直言 :)

于 2013-04-25T13:09:45.500 回答
0

你想什么时候流产?如果用户说“停止”需要太长时间?

在这两种情况下,改变你的

until MYTable.EOF;

until MYTable.EOF or Aborted;

然后在计时器触发或用户按键时设置您的 Aborted 布尔值(请注意,您必须在循环中使用 Application.ProcessMessages 才能使程序能够处理按键)。这不会您的处理例程中中止,而是在每条记录之后中止。如果这还不够快,您将不得不展示您的记录处理程序。

于 2013-04-24T09:32:20.997 回答