说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

VB如何在Visual Basic中实现异步执行程序

HTML文档下载 WORD文档下载 PDF文档下载
VB如何在Visual Basic中实现异步执行程序
郑州市金博大商务中心B座
郭继胜
---- 使用 Visual Basic 编写应用程序的开发人员一定都遇到过这样的情形:当你的应用程序要完成一个比较大的任务时,并且该任务是那种“独占式”的任务(比如:使用 Visual Basic 的函数 FileCopy 复制一个超过50兆字节的文件),如果不对程序作出特殊的处理,则用户将被迫面对一个象是被“挂起”的窗体,任凭你用鼠标怎样点击也没有任何反应,更糟糕的是当你从屏幕保护程序切换回该程序时会看到程序的窗体变成了一块“白布”,这更加给人一种“死机”的感觉(其实不仅是使用Visual Basic会遇到这种问题,使用其他的开发工具同样会存在,但其各自提供了自己的解决方法,这里我们姑且只讨论Visual Basic,至于其他的开发工具请参考它们的开发文档)。如何避免这种尴尬的界面出现呢?笔者在实践中发现了一种简单的办法,在这里介绍给大家,希望能对您有所帮助。

---- 这种办法是利用 Visual Basic 提供的创建ActiveX 部件的功能设计一个专门完成“大任务”的ActiveX 部件。Visual Basic 从5.0版本开始在创建ActiveX部件方面显示出前所未有的优秀品质。这里对ActiveX部件作如下简单介绍,以期适合不同的读者。Visual Basic所能设计的部件共有两种:一种是可视的部件;另一种是不可视的部件。可视的部件包括ActiveX控件和ActiveX文档,最常见的ActiveX控件比如现今各种高级开发工具(Inprise Delphi,Sybase PowerBuider等)都提供的按纽(Command或Button)、标签(Label)等等,ActiveX控件和窗体一起构成了应用程序与用户交互的界面。ActiveX文档使用在Internet应用程序中。由于我们的问题不涉及到可视的部件,所以这里不再赘述。

---- 不可视的部件又称为代码部件,包括Active DLL部件和ActiveX EXE部件两种。ActiveX部件的另一个名称是ActiveX服务器,之所以被称作服务器是由于ActiveX部件与使用它们的应用程序之间的关系可以被类比为服务器程序与客户端程序之间的关系:ActiveX部件封装了特定的功能或业务规则,应用程序不需要知道ActiveX部件是如何实现这些功能或业务规则的,只需要通过ActiveX部件提供的编程接口(API:Applacation Programming Interface ,ActiveX部件的API是由部件或其类的一系列属性、方法和事件构成的)传递应用程序的要求(通过属性或方法的参数),然后从部件的事件或其类的事件获得执行结果。根据ActiveX部件(ActiveX服务器)的执行方式可以把ActiveX部件分为进程内部件和进程外部件,所谓进程内部件即部件和使用它们的应用程序执行时共享同一个进程;而进程外部件却执行在自己的进程中,也可以这样认为:进程外部件的执行不影响使用它们的应用程序!显然,这个特性正是本文开始面对的那个问题所需要的。在部件中只有ActiveX EXE部件是进程外部件,因此利用这个特性我们可以创建一个ActiveX EXE部件来完成“大任务”,而应用程序窗体只显示一些任务的提示信息,直到ActiveX EXE部件的类的事件提示任务结束为止。这样应用程序就避免了那种呆板的“白布”窗体的出现,而能够响应任何来自用户的操作或者当从那些遮盖住它的程序切换回来时自行刷新。给用户的感觉是程序是在“异步”执行的。(注:关于创建ActiveX部件的详细信息请参考《Visual Basic联机手册》或MSDN文档)

---- 下面我们通过例子来看如何实现这一想法:在这个例子中我们假设应用程序窗体是一个一直显示当前时间的数字时钟,当你使其执行“大任务”直到任务的完成,这期间你会发现数字时钟窗体从来就没有被“挂起”过,仍然能够响应你的拖动操作和不停地显示时间。以下是实现这一程序和ActiveX EXE部件的步骤及源代码(以Visual Basic 6.0中文企业版为例):

---- 一、 创建ActiveX EXE部件(BigJobServer):

---- 步骤一:打开Visual Basic 6.0(或Visual Basic 5.0)新建一个Visual Basic工程,工程类型选择ActiveX EXE,在工程资源管理器中选中工程1,然后在属性窗口中将其名称改为 BigJobServer。

---- 步骤二:为工程添加一个Timer控件的容器窗体(添加窗体通过菜单 工程 >添加窗体 完成)。窗体名称改为 frmClock ;在窗体上放置一个Timer控件(从工具箱中选择Timer控件),名称改为 timClock。

---- 说明:添加该窗体的用意是提供一个执行任务的定时器(Timer控件)

---- 步骤三:设计实现“大任务”的类 BigJob(注:代码部件是通过各种类实现应用程序交给它的任务的,关于类的创建请参考《手册》或MSDN文档)默认情况下当你新建ActiveX EXE部件时Visual Basic为你添加了一个名为Class1的类(要增加类通过菜单 工程>添加类模块 完成),从工程资源管理器中选中Class1,然后在属性窗口中设置如下属性:

---- (名称): BigJob

---- Instancing: 5-MultiUse (可被创建多个实例,详细情况参考《手册》)编写API:为类BigJob添加方法和事件(通过菜单工具 >添加过程完成)部分代码及程序说明如下:

Private frmTimeClock As frmClock '声明定时器容器窗体
Private WithEvents oTimer As Timer '声明定时器(包括其事件)
Public Event JobStart() '声明任务开始事件
Public Event JobEnd() '声明任务结束事件

Private Sub Class_Initialize()
'---- 类初始化事件 ----
'在这里创建定时器窗体 frmTimeClock
'并引用定时器 oTimer
Set frmTimeClock = New frmClock
Load frmTimeClock
Set oTimer = frmTimeClock.timClock
oTimer.Enabled = False
End Sub

Private Sub Class_Terminate()
'类终止事件,释放定时器并卸载定时器窗体
Set oTimer = Nothing
Unload frmTimeClock
End Sub

Public Sub StartJob()
'方法 - 通知执行“大任务”
oTimer.Interval = 100
‘经过0.1秒时间开始执行任务
oTimer.Enabled = True
End Sub

Private Sub doBigJob()
'模拟的“大任务”是这个空耗时间的循环
'显然,这段代码在标准EXE程序中一定会造成“挂起”状态!
Dim lngTemp As Long
Dim lngSum As Long

For lngTemp = 1 To 10000000
lngSum = lngSum + 1
Next
End Sub

Private Sub oTimer_Timer()
'定时器周期到时开始执行任务
oTimer.Enabled = False
RaiseEvent JobStart '触发“开始执行”事件
doBigJob '执行“大任务”
RaiseEvent JobEnd '触发“任务结束”事件
End Sub

---- 现在保存工程:选择菜单 文件>保存工程,根据提示窗口选择合适的文件夹保存所有工程资源(工程文件,窗体文件,类文件)。

---- 二、 使用并调试BigJobServer部件:

---- 步骤一:选择菜单 运行 >全编译执行,可以看到除了Visual Basic进入运行工程 的状态之外看不到任何窗体出现,ActiveX EXE部件的调试比较特殊: 需要在另一个Visual Basic程序中进行。

---- 步骤二:最小化Visual Basic,然后启动另一个Visual Basic的实例,新建一个标 准EXE工程。选择菜单 工程>引用 ,在可引用的部件中我们可以找到 BigJobServer部件,选中该部件,按“确定”按纽返回。这样就建立了 应用程序和部件服务器间的联系。现在可以在这个工程中创建BigJob类 并使用其方法和事件了。

---- 步骤三:在默认的窗体Form1上放置如下控件并设置其属性(方法同前):

类型 名称 标题(Caption属性)
Label lblTime lblTime
Label lblMessage lblMessage
Timer timClock (无)
Command cmdStart 执行任务
步骤四:为该工程编写简单的代码:
Option Explicit
Dim WithEvents myJob As BigJob ‘声明BigJob对象(包括事件)
Private Sub Form_Load()
Set myJob = New BigJob ‘创建BigJob的实例
End Sub

Private Sub Form_Unload(Cancel As Integer)
Set myJob = Nothing '释放对象
End Sub

Private Sub cmdStart_Click()
myJob.StartJob '通知对象执行任务
End Sub

Private Sub myJob_JobStart()
'在对象的“开始”事件中给用户一些提示
lblMessage.Caption = "正在执行任务 ..."
End Sub

Private Sub myJob_JobEnd()
'在对象的“结束”事件中给用户一些提示
lblMessage.Caption = "任务完成!"
End Sub

Private Sub timClock_Timer()
'“数字时钟”在不间断地显示当前时间
lblTime.Caption = Format(Now, "HH:NN:SS")
End Sub

---- 步骤五:保存并运行这个测试工程会看到如下结果:当你按下“执行任务”按纽 后从提示可以知道那个可怕的“大任务”已经开始执行,直到程序提示任 务结束,这期间无论是拖动窗体还是时间的显示均不会受到影响。由此可 见程序被“挂起”的尴尬局面得到了解决。

---- 三、 补充说明:

---- 1、 上述程序在Visual Basic 6.0中文企业版上调试通过。

---- 2、 要在你的程序中实现这种方法,可以改进ActiveX EXE部件。比如在类BigJob中把doBigJob过程替换为你的具体任务;或通过添加属性来传递适当的任务参数等等。

---- 3、 关于ActiveX EXE部件的编译和发布问题,请参考《Visual Basic联机手册》或MSDN文档。
兼顾性能和兼容体验:HTML5时代的浏览器全面测试 Lisp的本质 Amazon工作环境恶劣员工高流失率 为何却依然能持续成功和创新? 对几个软件开发传统观点的质疑和反驳 [实战分析] 编写高效的JavaScript程序 Twitter的系统编程 百度高通达成合作 为Android终端提供云服务 EasyHadoop技术沙龙在北京、广州两地齐发 CloudStack技术沙龙:committer李学辉及中航信分享 思科为什么愿意花12亿美元收购云计算网络初创公司Meraki? 谷歌有麻烦了!联邦贸易委员会正调查其搜索业务 当数据中心遭遇污水 微软新能源数据中心的诞生 2012vForum:更加注重开发者 腾讯赵伟:Hive在腾讯分布式数据仓库的实践 Apple将在2013年启动香港数据中心的建设 顶级域名扩张受阻:ICANN透露部分域名存争议 硅谷创业教父Paul Graham:如何获得创业好点子? GDC2012特别报道:中西方游戏开发思想在这里融合 应用示例和对象是编程的未来吗? 为什么2012年HTML5发展远未达预期 当程序不再工作时,程序员说 独立游戏开发者易犯的9大致命错误 “Do Not Track”的前世今生 《Warcraft是怎样炼成的(三)》:从Demo到游戏 无限强大的超级马里奥AI 以Google第二代数据库产品MegaStore为理论模式 探索HBase系统 传Google明年推Chrome OS触摸屏上网本 下载自己过去的Tweets?用户准备好了吗? 微软任命研究部门新副总裁 负责北京等实验室 欧朋首席标准官:HTML5将在2014年成熟 开发利器:对游戏开发者最具价值的5类iOS应用 昨天真的真的受了刺激 怎樣將dbedit控件的事件和它所在的form方法相關起來? 如何实现DOS工作站连接到LINUX服务器 DB2技术讨论(5)如何在建好的数据库中设定数据库和表的维护信息 feeboby(诺曼之路) 请进,刚才IE出现js的问题,帖子结了,但分没加上去,另开新帖,100分送上 如何把两个系统合并为一个系统(两个独立的系统) 如何实现集成?? 请教一个apache2.0加tomcat4.3.x时访问目录控制问题 那里有Zend的反编译软件下啊? 大家给我提建议拉,java项目该如何做?交友 这样的asp.net程序消耗是不是太高? 满分求救: 通过 scope="session" 定义的bean 我想继续在包含页中使用。。 大家给个名字建议吧 BDE问题 那个说我骗你手提电脑的进来!!!!!!! 谁知道啊? 直接写内存的Win32 API? 向高手请教.NET下怎样实现聊天室功能? 请教一个apache2.0加tomcat4.3.x时访问目录控制问题 关于JFC的问题 如何鼠标指到单元格中,把单元格中的文字颜色改变 小弟菜鸟,请教一个小问题 初学者问题:关于Serialize()用法 寻求好的解决方法 新手求助?谁有较好的打印控件,或较好的解次方案? 申请数据结构-算法版主 初学者问题:MFC数据库(ACCESS) 那里可以找到interbase7的全部文档? 初学者问题:MFC建立数据库连接 请帮我编个简单的VC++程序,速回复,谢谢 初学者问题:MFC(FORMVIEW) 在System.DirectoryServices中如何通过NT用户组来取得组中的用户 高分:在命令提示符中登录mysql并执行包含多个mysql脚本 新手求助!!!! C#中的控制问题,大家来看看 急,哭,IIS下无法调试ASP。555,高手求你们帮帮我吧。 映射网络驱动器错误,我在公司机子上可以用,而在自家电脑上却报错,为什么?在线等待 sos pb巨大一个bug(还是我太菜了?),帮忙呀,兄弟们! 传值调用~,编译通过,可执行时出错 serialize(CArchive& ar)中怎样加载数组? 如何用VC从c代码得到汇编的代码? 如何在<form runat=server>...</form>内调用form外定义的变量? 如何鼠标指到单元格中,把单元格中的文字颜色改变 555~~~~ 100分求together for JBuilder 下载(不知为啥我的IE到borland上竟然无法打开那个弹出的下载页面) 如何定义listview控件中的指定文字的颜色? 我是初学jsp的虾米!请大家来帮我! 关于子窗体向父窗体取值问题 大脑极度混乱后的想法,请大家分析一下可行吗? 冲击波,怎么办? 您好 , 请教如何写一个服务程序 ? 高分求救-----怎么读出excel中的数据? 为什么明朝后期和清朝要闭关锁国呢? 已知一次函数y=3x-2,它的图象与反比例函数的图象只交于一点,求反比例函数的解析式 ?怎麼解释? 爱的定义是甚麼?跟喜欢有甚麼差别?要怎麼分辨是哪种爱? 无论是西北的腰鼓还是江南的二胡,它们都有独特的艺术个性.你还熟悉和喜欢哪些乐器?请谈谈你的体会. 什么是不计免赔险 汉翻英 :解决国与国之间争端的最好办法是通过联合国 在数学中什么叫仿写? 两个人距离很遥远要怎么去爱! 我叫xue yanyan ,想起英文名呢,不知道用什么英文名适合,急用 医学简答题 简述正常承认窦性心电图及房颤心电图的特征简洁答题即可 阿尔及利亚对摩洛哥撤回驻阿大使表示遗俄罗斯西北地区强风暴后电力全面恢复供联合国因资金不足减少肯尼亚难民粮食供中国代表:反对西方国家无端指责攻击中官方释疑北京单双号限行:单号单日双号德国法兰克福股市DAX指数10月31伦敦股市《金融时报》100种股票平均美国务卿将访沙特修补关系多米尼加登革热致98人死亡专家谈养老金并轨:待遇降低的改革肯定俄罗斯总统普京会见许其亮市经信委:温州六项重点任务完成率居全市发改委:苍南龙港列为国家新型城镇化温州15家市直单位年度述政:晒成绩 陈作荣:市发改委今年要力争完成限上投孔海龙:希望市经信委勇于做温州工业经郑州整治7条河道方案出台 103个排134路公交爆胎伤人案“二胎保证书”只是一纸轻佻承诺劫匪:“后悔,抢劫过程中就不想抢了”2月上旬还得冷几天被指贷19800元未按时还国王的战争王牌教官十方神王武道仙轮大明1617圣印至尊感情年代重启高一重生之文娱高手绝世神皇无限进阶马家大院旅游宝通寺旅游西北街旅游北溪村旅游两江四湖日月湾码头旅游莲花庄旅游马太鞍旅游怡和午炮旅游梅峰寺旅游三清殿旅游九鲤湖旅游
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘