一般, 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+高级程序设计篇》,并进行整理)
分享到:
相关推荐
ADO异步查询显示进度条[文].pdf
ADO异步查询显示进度条[归类].pdf
实例62 使用异步机制作获取网页 实例63 发送SMTP邮件 实例64 邮件提示器 实例65 网页上下传器 实例66 自己制作服务器 实例67 工具 实例68 工具 实例69 聊天服务端 实例70 聊天客户端 第五篇 数据库编程 ...
实例067 利用选择控件实现复杂查询 85 2.6 ListView控件应用 87 实例068 ListView控件间的数据移动 87 实例069 将数据库数据添加到ListView控件 90 实例070 在ListView控件中实现修改功能 91 实例071 在...
实例067 利用选择控件实现复杂查询 85 2.6 ListView控件应用 87 实例068 ListView控件间的数据移动 87 实例069 将数据库数据添加到ListView控件 90 实例070 在ListView控件中实现修改功能 91 实例071 在...
实例067 利用选择控件实现复杂查询 85 2.6 ListView控件应用 87 实例068 ListView控件间的数据移动 87 实例069 将数据库数据添加到ListView控件 90 实例070 在ListView控件中实现修改功能 91 实例071 在...
实例067 利用选择控件实现复杂查询 85 2.6 ListView控件应用 87 实例068 ListView控件间的数据移动 87 实例069 将数据库数据添加到ListView控件 90 实例070 在ListView控件中实现修改功能 91 实例071 在...
57 2.2 Button控件应用 58 实例053 在Button按钮中显示图标 58 2.3 ComboBox控件应用 59 实例054 将数据表中的字段添加到ComboBox控件 59 实例055 带查询功能的ComboBox控件 61 2.4 ...
1.4.11 First函数——返回查询结果的第一个记录 55 1.4.12 FirstDayOfWeek属性——获取或设置一周中的第一天 56 1.4.13 Format方法——格式化字符串 56 1.4.14 GETDATE函数——返回当前系统日期和时间 58 1.4.15 ...
2 <br>0003 设置程序代码行序号 3 <br>0004 开发环境全屏显示 3 <br>0005 设置窗口的自动隐藏功能 3 <br>0006 根据需要创建所需解决方案 4 <br>0007 如何使用“验证的目标架构”功能 4 ...
[2]异步选择 - WSAAsyncSelect [3]---事件选择 - WSAEventSelect [4]---重叠I [5]---完成端口 IP所在地查询器 如题。 jpeglib_demo 处理Jpeg图片。 KeyHook 键盘钩子,截获键盘信息。 Kugou7+UI 界面设计。学习...
11.1 在文本控制台中显示进度条 402 11.2 避免在编写回调函数时使用lambda 404 11.3 在tkSimpleDialog函数中使用默认值和区间 405 11.4 给Tkinter列表框增加拖曳排序能力 406 11.5 在Tkinter部件中输入一个重音...