ADO异步查询显示进度条

简介:     一般, A D O都是以同步的方式来处理数据。这就是说,当A D O开始处理数据后,应用程序必须等到A D O处理完毕之后才可以继续执行。但是除了同步执行方式之外, A D O也提供了异步执行的方式,允许当A D O处理时,应用程序仍然能够先继续执行。

    一般, A D O都是以同步的方式来处理数据。这就是说,当A D O开始处理数据后,应用程序必须等到A D O处理完毕之后才可以继续执行。但是除了同步执行方式之外, A D O也提供了异步执行的方式,允许当A D O处理时,应用程序仍然能够先继续执行。而当A D O处理数据完毕之后, A D O会以事件的方式通知应用程序,此时应用程序可以再根据A D O执行的结果来采取相应的动作。


    使用异步执行方式有许多用途,例如,如果应用程序需要处理花费大量时间的动作,那么A D O可以选择以异步执行方式让A D O在后台执行,而让应用程序继续处理图形用户接口或用户输入的数据。


    在A D O中使用异步执行方式非常简单,只需要对A D O数据集的E x e c u t e O p t i o n s属性值进行适当的设定即可。现在就让我们以一实际的范例应用程序来说明如何让A D O以异步的方式来处理数据。


1) 在D e l p h i集成开发环境中关闭所有的项目。


2) 建立一个新的应用程序项目,在主窗体中放入TA D O C o n n e c t i o n对象连接到数据库。


3) 在主窗体中放入TA D O D a t a S e t组件。设定它的C o n n e c t i o n属性值为步骤2) 的TA D O C o n n e c t i o n,并且在它的C o m m a n d Te x t属性值中使用Select * from ADOTe s t D a t a s以取得所有的数据。再设定它的A c t i v e属性值为Tr u e以打开范例数据表。


4) 放入TDataSource组件,设定它的DataSet属性值为步骤3) 加入的TADODataSet组件。


5) 放入T D B N a v i g a t o r和T D B G r i d组件,设定它们的D a t a S o u r c e组件为步骤4加入的T D a t a S o u r c e组件。


6) 在主窗体中放入两个T B u t t o n组件以及一个T P r o g r e s s B a r组件,并且设定它的相关属性值。

 

7) 最后在主窗体中放入一个TA D O C o m m a n d组件。设定它的C o n n e c t i o n属性值为步骤2) 的TA D O C o n n e c t i o n,并且在它的C o m m a n d Te x t属性值中使用S e l e c t count(*) from ADOTe s t D a t a s以便从A D O Te s t D a t a s数据表中取得所有数据的笔数。


8) 在主窗体的O n A c t i v a t e事件处理程序中撰写如下的程序代码:
p r o c e d u r e TForm1.FormActivate(Sender: TObject);
v a r
    sRecNo : String;
b e g i n
    ProgressBar1.Max := ADOCommand1.Execute.Fields.Item[0].Value;
    sRecNo := IntToStr(ProgressBar1.Max);
    Self.Caption := '共有' + sRecNo + ' 笔数据' ;
e n d ;

O n A c t i v a t e事件处理程序首先执行TA D O C m m a n d的S Q L命令,并且从它回传的暂时R e c o r d s e t对象中取出A D O Te s t D a t a s数据表中所有数据的笔数,然后再指定给T P r o g r e s s B a r的M a x值,最后指定给窗体的C a p t i o n属性值。


9) 双击窗体中的e o A s y n c F e t c h N o n B l o c k i n g按钮,并且在它的O n C l i c k事件处
理程序中撰写如下的程序代码:
p r o c e d u r e TForm1.Button2Click(Sender: TObject);
b e g i n
t r y
    ADODataSet1.Active := False;
    ADODataSet1.ExecuteOptions := [eoAsyncFetchNonBlocking];
f i n a l l y
    lStart := GetTickCount;
    ADODataSet1.Active := True;
e n d ;
e n d ;

在上面的程序代码中先关闭步骤3) 的TA D O D a t a S e t,再设定它的E x e c u t e O p t i o n s属性值为使用异步方式来存取数据。最后再打开步骤3) 的TA D O D a t a S e t组件,从A D O Te s t D a t a s数据表中取得数据。


10) 双击窗体中的e o A s y n c F e t c h按钮,并且在它的O n C l i c k事件处理程序中撰
写如下的程序代码:
p r o c e d u r e TForm1.Button1Click(Sender: TObject);
b e g i n
t r y
    ADODataSet1.Active := False;
    ADODataSet1.ExecuteOptions := [eoAsyncFetch];
f i n a l l y
    lStart := GetTickCount;
    ADODataSet1.Active := True;
e n d ;
e n d ;

在上面的程序代码中先关闭步骤3) 的TA D O D a t a S e t,再设定它的E x e c u t e O p t i o n s属性值为使用同步方式来存取数据,再打开步骤3) 的TA D O D a t a S e t组件,从A D O Te s t D a t a s数据表中取得数据。


在异步方式中, A D O会以O n F e t c h P r o g r e s s事件来通知应用程序A D O还在处理数据之中,并且以O n F e t c h C o m p l e t e事件来通知应用程序A D O已经处理数据完毕了。
程序员可以在这两个事件处理程序中撰写程序代码来处理这两种情形。下面是范例应用程序在这两个事件处理程序中实现的程序代码。


11) 在步骤3) 的TA D O D a t a S e t组件的O n F e t c h P r o g r e s s事件处理程序中撰写如下的程序代码:
p r o c e d u r e TForm1.ADODataSet1FetchProgress(DataSet: TCustomADODataSet;
Progress, MaxProgress: Integerv; a r EventStatus: TEventStatus);
b e g i n

 //注意,每次循环的进度步距不是1,在这有可能是15,第一次提取的记录数量也很大,所以对于小数据量,没有意义
    ProgressBar1.Position := Progress;
e n d ;

上面的程序代码只是在A D O持续处理数据时不断更新主窗体中T P r o g r e s s B a s e
的显示状态。


12) 在步骤3) 的TA D O D a t a S e t组件的O n F e t c h C o m p l e t e事件处理程序中撰写如下的程序代码:
p r o c e d u r e TForm1.ADODataSet1FetchComplete(DataSet: TCustomADODataSet;
c o n s t Error: Error; v a r EventStatus: TEventStatus);
b e g i n
    lEnd := GetTickCount;
    S h o w M e s s a g e ( '总共花了' + FloatToStr((lEnd - lStart) / 1000.0) 秒+ ' ') ;
e n d ;

上面的程序代码是当A D O处理完数据之后便显示一个对话框,显示A D O处理数据所花费的时间。
现在请编译并且执行这个范例应用程序。图3 - 1 3是以异步的方式来存取A D O Te s t D a t a s这个范例数据表中数据的画面。从图中可以看到,当A D O存取数据时应用程序仍然可以不断地更新主窗体中的T p r o g r e s s B a r。如果使用同步的方式执
行,T P r o g r e s s B a r便无法这样更新状态。此时我们也可以移动主窗体的位置等,可见应用程序不会因为A D O在存取大量的数据而造成应用程序无法继续工作。


当A D O以异步的方式执行时,O n F e t c h P r o g r e s s和O n F e t c h C o m p l e t e事件可以帮助程序员取得非常有用的状态信息。


如果你也执行这个范例应用程序,那么可以比较一下当A D O在同步执行模式和异步执行模式中处理数据时哪一种模式比较有效率。可能你会惊讶地发现异步执行模式可以提供更好的执行效率

(邦畿千里,摘自李维《Delphi 5.x ADO/MTS/COM+高级程序设计篇》,并进行整理)

相关文章
|
3月前
|
开发框架 .NET C#
WPF/C#:显示分组数据的两种方式
WPF/C#:显示分组数据的两种方式
61 0
|
C#
WPF更新绑定字段
WPF更新绑定字段
106 0
|
数据库 C#
C#编程学习18:使用多文档窗体框架利用DataGridView对Access数据表进行增删改及导出excel操作
C#编程学习18:使用多文档窗体框架利用DataGridView对Access数据表进行增删改及导出excel操作
C#编程学习18:使用多文档窗体框架利用DataGridView对Access数据表进行增删改及导出excel操作
|
消息中间件 安全 C#
WinForm-跨线程更新UI控件常用方法
WinForm-跨线程更新UI控件常用方法
703 0
WinForm-跨线程更新UI控件常用方法
|
算法 数据库 内存技术
【视频】自然框架之分页控件的使用方法(一) PostBack方式的一般分页方式
前言:分页控件的优点   1、 按需所取 —— 需要几条记录就从数据库里提取几条记录,不会多取。 2、 使用简单 —— 设置几个属性就可以实现分页的功能。 3、 多种分页算法 —— (即分页用的SQL语句)可以根据不同的需求灵活选择 4、 支持多种数据库 —— 用不同的分页算法对应不同的数据库。
1113 0
|
SQL 算法 测试技术
我自己写的一个分页控件(源码和演示代码)PostBack分页版 for vs2003、SQL Server
温馨提示:asp.net分页控件已经升级了,基于.net2.0 ,支持多种数据库。正式命名为:QuickPager Asp.net 2.0 分页控件。 网站:www.natureFW.com 下载:http://www.naturefw.com/down/List1.aspx 在线演示:http://demo.naturefw.com 上一篇随笔:我的分页控件(未完,待续)——控件件介绍及思路 一、分页控件的工作层次    如果按照三层的划分方式来说,应该算作工作在 UI层 和 逻辑层。
1310 0
|
C#
WPF使用异步+绑定的方式处理大数据量
原文:WPF使用异步+绑定的方式处理大数据量      WPF的优势在于界面处理,即使是这样,在面对大数据量的时候也免不了界面假死,同一个线程里处理界面跟大数据量,这是不可避免的。解决办法还是有的,可以使用分页加载,虚拟加载,动态加载,增加条件限制...      比较好的解决办法是使用异步+绑定的方式,即绑定控件的数据源,异步获取数据。
1221 0
|
C#
WPF中实现PropertyGrid(用于展示对象的详细信息)的三种方式
原文:WPF中实现PropertyGrid(用于展示对象的详细信息)的三种方式 由于WPF中没有提供PropertyGrid控件,有些业务需要此类的控件。
1996 0