在VB中异步执行程序

2016-02-19 18:28 17 1 收藏

下面是个超简单的在VB中异步执行程序教程,图老师小编精心挑选推荐,大家行行好,多给几个赞吧,小编吐血跪求~

【 tulaoshi.com - 编程语言 】

使用VisualBasic编写应用程序的开发人员一定都遇到过这样的情形:当你的应用程序要完成一个比较大的任务时,并且该任务是那种“独占式”的任务(比如:使用函数FileCopy复制一个超过50MB的文件),如果不对程序作出特殊的处理,则用户将被迫面对一个像是被“挂起”的窗体,任凭你用鼠标怎样点击也没有任何反应,更糟糕的是当你从屏幕保护程序切换回该程序时会看到程序的窗体变成了一块“白布”,这更加给人一种“死机”的感觉。如何避免这种尴尬的界面出现呢?笔者在实践中发现了一种简单的办法,在这里介绍给大家,希望能对您有所帮助。

----这种办法是利用VisualBasic提供的创建ActiveX部件的功能设计一个专门完成“大任务”的ActiveX部件。这里对ActiveX部件作如下简单介绍,以期适合不同的读者。VisualBasic所能设计的部件共有两种:一种是可视的部件;另一种是不可视的部件。ActiveX控件和窗体一起构成了应用程序与用户交互的界面,ActiveX文档使用在Internet应用程序中。由于我们的问题不涉及到可视的部件,所以这里不再赘述。

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

----下面我们通过例子来看如何实现这一想法:这个例子中,我们假设应用程序窗体是一个一直显示当前时间的数字时钟,当你使其执行“大任务”直到任务的完成,这期间你会发现数字时钟窗体从来就没有被“挂起”过,仍然能够响应你的拖动操作和不停地显示时间。以下是实现这一程序和ActiveXEXE部件的步骤及源代码:1.创建ActiveXEXE部件(BigJobServer)----步骤一:打开VisualBasic6.0新建一个VB工程,工程类型选择ActiveXEXE,在工程资源管理器中选中工程1,然后在属性窗口中将其名称改为BigJobServer。

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

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

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

----(名称):BigJob

----Instancing:5-MultiUse

----编写API:为类BigJob添加方法和事件(通过菜单工具添加过程完成)部分代码及程序说明如下:

PrivatefrmTimeClockAsfrmClock
  '声明定时器容器窗体
  PrivateWithEventsoTimerAsTimer
  '声明定时器(包括其事件)
  PublicEventJobStart()
  '声明任务开始事件
  PublicEventJobEnd()
  '声明任务结束事件
  
  PrivateSubClass_Initialize()
  '----类初始化事件----
  '在这里创建定时器窗体frmTimeClock
  '并引用定时器oTimer
  SetfrmTimeClock=NewfrmClock
  LoadfrmTimeClock
  SetoTimer=frmTimeClock.timClock
  oTimer.Enabled=False
  EndSub
  
  PrivateSubClass_Terminate()
  '类终止事件,
  释放定时器并卸载定时器窗体
  SetoTimer=Nothing
  UnloadfrmTimeClock
  EndSub
  
  PublicSubStartJob()
  '方法-通知执行“大任务”
  oTimer.Interval=100
  '经过0.1秒时间开始执行任务
  oTimer.Enabled=True
  EndSub
  
  PrivateSubdoBigJob()
  '模拟的“大任务”
  是这个空耗时间的循环
  '显然,这段代码在标准EXE程序中
  一定会造成“挂起”状态!
  DimlngTempAsLong
  DimlngSumAsLong
  
  ForlngTemp=1To10000000
  lngSum=lngSum+1
  Next
  EndSub
  
  PrivateSuboTimer_Timer()
  '定时器周期到时开始执行任务
  oTimer.Enabled=False
  RaiseEventJobStart'触发“开始执行”事件
  doBigJob'执行“大任务”
  RaiseEventJobEnd'触发“任务结束”事件
  EndSub

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

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

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

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

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

 -width="20">类型->-width="20">名称->-width="40">标题(Caption属性)->-width="20">Label->-width="20">lblTime->-width="40">lblTime->-width="20">Label->-width="20">lblMessage->-width="40">lblMessage->-width="20">Timer->-width="20">timClock->-width="40">(无)->-width="20">Command->-width="20">cmdStart->-width="40">执行任务->

----步骤四:为该工程编写简单的代码:

OptionExplicit
  DimWithEventsmyJobAsBigJob
  '声明BigJob对像(包括事件)
  PrivateSubForm_Load()
  SetmyJob=NewBigJob'创建BigJob的实例
  EndSub
  
  PrivateSubForm_Unload(CancelAsInteger)
  SetmyJob=Nothing'释放对像
  EndSub
  
  PrivateSubcmdStart_Click()
  myJob.StartJob
  '通知对像执行任务
  EndSub
  
  PrivateSubmyJob_JobStart()
  '在对像的“开始”
  事件中给用户一些提示
  lblMessage.Caption=“正在执行任务..."
  EndSub
  
  PrivateSubmyJob_JobEnd()
  '在对像的“结束”
  事件中给用户一些提示
  lblMessage.Caption=“任务完成!"
  EndSub
  
  PrivateSubtimClock_Timer()
  '“数字时钟”在不间断地
  显示当前时间
  lblTime.Caption=Format(Now,“HH:NN:SS")
  EndSub

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

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)3.补充说明上述程序在VisualBasic6.0中文企业版上调试通过。要在你的程序中实现这种方法,可以改进ActiveXEXE部件。比如在类BigJob中把doBigJob过程替换为你的具体任务;或通过添加属性来传递适当的任务参数等等。关于ActiveXEXE部件的编译和发布问题,请参考《VisualBasic联机手册》或MSDN文档。->

来源:http://www.tulaoshi.com/n/20160219/1617791.html

延伸阅读
要想控制拨号网络,就要使用RemoteAccessService(RAS)API,这个API最早是在WindowsforWorkgroup3.11中出现的,现在它已经成为Win32API的一个组成部分。挂断拨号网络的函数叫RasHangUp,这个函数的功能和用法都很简单,它只有一个参数,就是要挂断的拨号网络连接的句柄。我们可以利用RasEnumConnections获得当前系统所有RAS连接(通常我们的系统...
UDP协议是一种无连接协议,两台计算机之间的数据传输类似于传递邮件:消息从一台计算机发送到另一台计算机,但是两者之间没有明确的连接。 由于UDP协议不需要显式的连接,就需要在两个Winsock控件中间发送数据,关键需要完成以下的三步: 1.将RemoteHost属性设置为另一台计算机的名称。 2.将RemotePort属性设置为第二个控件的Loca...
众所周知,VisualBasic是功能非常强大的多媒体开发工具,它有丰富的函数和方法处理各种各样的多媒体信息,能够很灵活的操作图形、声音、动画、影象等多媒体素材。但有时我们使用VisualBasic开发非多媒体应用程序,并不需要在应用程序中大量的使用声音,而只是需要在特定的场合出现。如Windows的警告声。这就要求程序员在恰当的环境中恰当的使用...
鼠标是WINDOWS环境下不可缺少的输入工具,在应用程序中灵活地使用鼠标功能,会给工作带来极大的方便.VISUAL FOXPRO6.0和VISUAL BASIC6.0是MICROSOFT VISUAL STUDIO98面向对象的可视化开发环境,它功能非常强大,而且设计程序简单实用.它提供了与鼠标操作有关的事件和API函数,所以编写鼠标功能程序就变得非常简单,只需在程序中调用这些事件和API...
在标准工程中添加一个公共对话框和两个按钮即可尝试本例: OptionExplicit '删除文件的API PrivateDeclareFunctionSHFileOperationLib"shell32.dll"Alias"SHFileOperationA"(lpFileOpAsToBin)AsLong '清空回收站的API PrivateDeclareFunctionSHEmptyRecycleBinLib"shell32.dll"Alias"SHEmptyRecycleBinA"...

经验教程

990

收藏

94
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部