程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> Visual Basic語言 >> VB綜合教程 >> 在VB中異步執行程序

在VB中異步執行程序

編輯:VB綜合教程
使用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

----現在保存工程:選擇菜單文件>保存工程,根據提示窗口選擇合適的文件夾保存所有工程資源(工程文件,窗體文件,類文件)。

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

----步驟五:保存並運行這個測試工程,會看到如下結果:當你按下“執行任務”按紐後從提示可以知道那個可怕的“大任務”已經開始執行,直到程序提示任務結束,這期間無論是拖動窗體還是時間的顯示均不會受到影響。由此可見程序被“掛起”的尴尬局面得到了解決。

3.補充說明

  • 上述程序在VisualBasic6.0中文企業版上調試通過。
  • 要在你的程序中實現這種方法,可以改進ActiveXEXE部件。比如在類BigJob中把doBigJob過程替換為你的具體任務;或通過添加屬性來傳遞適當的任務參數等等。
  • 關於ActiveXEXE部件的編譯和發布問題,請參考《VisualBasic聯機手冊》或MSDN文檔。
  • ->

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved