何偉
(甘肅省天水市職業技術學校,甘肅 天水 741000)
在使用VB語言編程過程中,如果遇到循環次數過多的循環命令或循環的嵌套層次較多時,很容易出現假死甚至假死機現象,而且循環執行的過程中用戶無法進行中斷。隨著操作系統的不斷完善,現在這種情況變成了“程序未響應”現象。在循環體中,如果加入一個進度條顯示命令,也根本看不到進度的顯示,想停下來,各種命令按鈕也不再起作用。隨著社會的發展需求,我們對軟件的要求并不是短小精悍,而是更加注重人性化操作。例如有一段命令需要執行1萬次,在執行的過程中應該能隨時了解運行的情況,而且隨時可以終止或暫停,尤其是在程序執行過程中,CPU占用資源要盡量少,不影響其他軟件的工作,這樣一來,再復雜的程序我們都可耐心等待。如果程序能自動根據計算機的實際配置調整計算機CPU的占用率,那就再好不過了。經過本人長期的摸索探討,終于找到一個較好的解決辦法:利用Timer定時器控件能設定循環的時間,再根據自己需求設定參數可更改循環數值,我們剛好利用它的這一獨特性來巧妙解決問題。
我們在利用高級語言程序進行編程過程中,在處理具有相同的、有規律性的重復操作時,簡潔的辦法都會使用循環語句來處理。
用一個簡單的程序來說明如下:
例如,計算s=1+2+3+……+n
如果程序要求從1加至100,這個程序則很簡單,使用循環語句命令如下:


這個程序命令很簡單,就是從1加到100,循環重復執行S=S+i語句100次,就求出了結果。這個程序初學者也能輕松掌握和理解,這個程序經常作為初學者的教學累加實例。
但理論和實際往往有一定的差別,以FOR循環命令為例,編程命令在使用過程中,如果遇到大的循環命令或循環的嵌套,很容易出現假死甚至死機現象,而且循環執行的過程中用戶無法中斷。在進度條和很多軟件中的也不同,經常只顯示第一步和最后一步,中間的過程并不顯示。例如我們如果要計算從1加到100萬或者從1加到100億,這段程序的執行就變得完全不同,即便配置和運算速度高的計算機,隨著運算次數的越來越多,運算數據的不斷增加,當達到機子運算極限時,就會出現假死或死機現象。
那么我們如何解決這個問題呢?經過本人多次長期的摸索探討,終于找到一個較好的解決辦法,那就是利用VB中的Timer定時器控件。我們知道Timer定時器控件功能是在指定的時間間隔內反復觸發指定窗口的定時器事件,我們可以看到這個控件的功能和循環語句是多么的相像,唯一不同點就是這個控件能設定循環的時間,所以我們剛好利用它的這一獨特的特性來解決問題。
我們現在重新編寫上段程序,步驟如下:
(1)添加控件:(為了使程序方便大家閱讀,控件都使用默認名稱)
定時器Timer1放入循環體,初始要設置成禁用,即Enabled項為False
按鈕 Command1'用于控制程序的“開始”和“繼續”
按鈕 Command2'用于控制程序的“暫停”
進度條ProgressBar1'用于顯示和查看程序運行進度
文本框Text1 '用于顯示i的當前值
文本框Text2 '用于顯示S的當前值
(2)添加代碼:
Dim i as Double'用于控制循環運行次數,由于數據量大,就定義成雙精度
Dim SAs Double'用于計算和值
Private Sub Form_Load()'程序初始,定義一些控件的初始值
i=0'初始循環的次數
S=0'初始和值
Timer1.Interval=10 '設置定時器的運行速度,單位毫秒,目前為10毫秒
ProgressBar1.Max=10000'定義進度條的最大值
ProgressBar1.Value=0'初始進度條進度,當前為0
End Sub
Private Sub Command1_Click()
Timer1.Enabled=True'只需讓定時器工作,循環就開始
End Sub
Private Sub Timer1_Timer() '計時器控件、放置循環體
i=i+1
If計數<=10000 then
S=S+i
ProgressBar1.Value=i'顯示當前進度
Text1.text=i'顯示 i的當前值
Text2.text=S'顯示S的當前值
Else
Timer1.Enabled=False'循環結束
End If
End Sub
Private Sub Command2_Click()'控制循環結束或暫停按鈕
Timer1.Enabled=False'定時器停止,循環結束
End Sub
程序執行主要過程是,兩個按鈕的作用只是控制定時器的“啟用”和“禁用”,定時器內部的IF語句控制程序是否結束,兩個文本框,一個顯示i值,一個顯示S值,配合進度條讓程序的執行不顯得單調,用戶可以很容易判斷出,程序還需執行多少時間。經過改編程序后,其優點是:在目前的情況下,不論多么配置低檔的計算機,都能平穩地運行代碼,而且隨時可以暫停或停止,進度條也真正開始顯示實際進度。但缺點是:顯而易見,命令多了很多,也復雜了很多,如果一個軟件中出現諸多的循環體,命令行要增加許多倍。而且,資源的消耗雖然變小了,但運行的時間增加了幾百倍。
所以程序至此,雖然解決了主要問題,但還有不少缺點,需要我們進一步分析解決:
仔細深入分析,問題一,程序運行時間過長。直接使用For循環,大循環容易造成資源消耗過大,導致死機現象。而使用Timer控件,則出現資源浪費,運行時間過長。但我們如果將這兩者巧妙結合,這個問題就迎刃而解了,所以我們得到了更好的解決方法,就是將Timer1內部中所有的命令看成一個<命令行>,原程序可表示為:
Private Sub Timer1_Timer()
<命令行>
End Sub
這樣,控件Timer1每次只執行一次<命令行>,運行穩定,但資源浪費嚴重,速度較慢,所以我們進一步可將程序改寫如下:
Private Sub Timer1_Timer()
for j=1 to 500'每次執行500次
<命令行>
next j
End Sub
根據自己需求或計算機配置可更改循環數值,這樣一來,兩者兼備,程序運行既平穩,速度也不慢。這樣我們就很好地解決了第一個問題。
存在的第二個問題是:循環命令多,程序變得復雜。
經過改進的程序中用到100個循環,按最初的設計我們需要添加100個Timer控件,這樣程序變得更加龐大而且顯得笨拙。經過探究思索,我們僅僅需要利用一個選擇語句Select,就可巧妙地解決問題。
程序改寫如下:
先定義一個變量K,由按鈕或命令控制其數據。
Private Sub Timer1_Timer() '計時器控件、放置循環體
Select case K 'K為循環控制參數
Case 0
<循環體1>
Case 1
<循環體2>
……
End Select
End Sub
我們現在看到,循環增加了很多,但命令并不是成倍增長,增加量并不多。如果還覺得程序體太長,不宜編寫和調試,還可使用函數,再次進行修改如下:
Private Sub Timer1_Timer() '計時器控件、放置循環體
Select case K 'K為循環控制參數
Case 0:Call自定義函數A
Case 1:Call自定義函數B
……
End Select
End Sub這樣我們就很好地解決了第二個問題。
至此,我們經探究設計,終于找到一個較好的解決辦法,那就是利用VB中的Timer定時器控件,解決了直接使用For循環,程序運行時間過長,容易造成資源消耗過大,導致死機的現象。而使用Timer控件,又會出現資源浪費。但我們如果將這兩者結合,就是將Timer1內部中所有的命令看成一個<命令行>,這個問題就迎刃而解了,進一步我們利用一個選擇語句Select和函數,就很巧妙地解決了以上問題。
[1]趙曉麗.基于S p r i n g的定時器的應用實現[J].太原師范學院學報:自然科學版,2015(4):48-53.
[2]任君玉,黎國文.網絡中的定時器技術[J].電腦知識與技術:學術交流,2011(7 X):5094-5095.
[3]侯婷.淺談V B F OR循環嵌套的運行機制[J].教育教學論壇,2012(9):169-180.