APP下载

巧用Timer定时器解决VB中循环造成的假死现象

2018-01-22何伟

电脑与电信 2017年11期
关键词:死机控件命令

何伟

(甘肃省天水市职业技术学校,甘肃 天水 741000)

1 引言

在使用VB语言编程过程中,如果遇到循环次数过多的循环命令或循环的嵌套层次较多时,很容易出现假死甚至假死机现象,而且循环执行的过程中用户无法进行中断。随着操作系统的不断完善,现在这种情况变成了“程序未响应”现象。在循环体中,如果加入一个进度条显示命令,也根本看不到进度的显示,想停下来,各种命令按钮也不再起作用。随着社会的发展需求,我们对软件的要求并不是短小精悍,而是更加注重人性化操作。例如有一段命令需要执行1万次,在执行的过程中应该能随时了解运行的情况,而且随时可以终止或暂停,尤其是在程序执行过程中,CPU占用资源要尽量少,不影响其他软件的工作,这样一来,再复杂的程序我们都可耐心等待。如果程序能自动根据计算机的实际配置调整计算机CPU的占用率,那就再好不过了。经过本人长期的摸索探讨,终于找到一个较好的解决办法:利用Timer定时器控件能设定循环的时间,再根据自己需求设定参数可更改循环数值,我们刚好利用它的这一独特性来巧妙解决问题。

2 问题的提出

我们在利用高级语言程序进行编程过程中,在处理具有相同的、有规律性的重复操作时,简洁的办法都会使用循环语句来处理。

用一个简单的程序来说明如下:

例如,计算s=1+2+3+……+n

如果程序要求从1加至100,这个程序则很简单,使用循环语句命令如下:

这个程序命令很简单,就是从1加到100,循环重复执行S=S+i语句100次,就求出了结果。这个程序初学者也能轻松掌握和理解,这个程序经常作为初学者的教学累加实例。

但理论和实际往往有一定的差别,以FOR循环命令为例,编程命令在使用过程中,如果遇到大的循环命令或循环的嵌套,很容易出现假死甚至死机现象,而且循环执行的过程中用户无法中断。在进度条和很多软件中的也不同,经常只显示第一步和最后一步,中间的过程并不显示。例如我们如果要计算从1加到100万或者从1加到100亿,这段程序的执行就变得完全不同,即便配置和运算速度高的计算机,随着运算次数的越来越多,运算数据的不断增加,当达到机子运算极限时,就会出现假死或死机现象。

3 初步解决方案

那么我们如何解决这个问题呢?经过本人多次长期的摸索探讨,终于找到一个较好的解决办法,那就是利用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值,配合进度条让程序的执行不显得单调,用户可以很容易判断出,程序还需执行多少时间。经过改编程序后,其优点是:在目前的情况下,不论多么配置低档的计算机,都能平稳地运行代码,而且随时可以暂停或停止,进度条也真正开始显示实际进度。但缺点是:显而易见,命令多了很多,也复杂了很多,如果一个软件中出现诸多的循环体,命令行要增加许多倍。而且,资源的消耗虽然变小了,但运行的时间增加了几百倍。

4 优化解决方案

所以程序至此,虽然解决了主要问题,但还有不少缺点,需要我们进一步分析解决:

仔细深入分析,问题一,程序运行时间过长。直接使用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这样我们就很好地解决了第二个问题。

5 结语

至此,我们经探究设计,终于找到一个较好的解决办法,那就是利用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.

猜你喜欢

死机控件命令
提醒
只听主人的命令
基于.net的用户定义验证控件的应用分析
关于.net控件数组的探讨
移防命令下达后
脸死机了
这是人民的命令
基于嵌入式MINIGUI控件子类化技术的深入研究与应用
计算机“死机”故障原因与排除
计算机“死机”故障原因与排除