微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 测试测量 > Labview > 通过labview事件结构贩卖机对事件结构常见错误总结(一)

通过labview事件结构贩卖机对事件结构常见错误总结(一)

时间:10-02 整理:3721RD 点击:

1。  程序结构不合理
在刚开始学习事件结构的时候,很多会员都会出现这样的情况。
虽然在程序中使用了事件结构,但并没有完全使用事件结构的思想,而是借
助 CASE 或其它结构来实现;


上图中二个红色框框中部分,一个是显示刚才购买的饮料的 VI,另一个是
显示找回的零钱 VI,程序中已经使用了事件结构了,但是事件结构之后,又会
再通过 CASE 来判断对应的状态再执行对应的程序。以找回零钱为例,这个子
VI 只有在“Change  Back”这个按钮按下后才需要调用的,这样就没必要每种
事件发生后都检查一下是否需要调用这个子 VI,完全可以将这个子 VI 放入到
“Change  Back.值改变”这个事件分支里面,而不是每次事件后都判断一次,
否则程序结构就变得比较混乱了。其它部分也类似。
这里也并不是说一定不能在事件结构后面加一个 CASE 之类的节点,
要看实际的程序要求,如果每一个事件处理后都需要做的工作,那么就可以在事
件结构后面添加这部分公用的功能,比如这次竞赛中如果使用了消息提示框,提
示每次操作的结果,比如投了一个硬件、买了一瓶饮料等。这个提示框是响应每
一个事件之后都必须处理的,这个提示框就可以放到事件结构后面,如下图所示:


可以参考一下我所贴出的程序的结构。
之前在论坛中还出现过其它事件结构的用法,比如一个 WHILE 循环
+CASE,然后某个 CASE 分支里面又有一个事件结构的结构,这种结构非常容
易导致死锁,还有就是循环里面带有二个事件结构的程序,这些都是不合理的结
构,可以参考一下自带的帮助中相关事件结构的说明。
2。超时事件分支的使用不够合理
程序中要求投币后或购买物品后要对相应的控件的禁用属性进行控制,比如
钱不够时应该禁用或隐藏购买的控件,从而使用用户无法购买饮料。大部分程序
都是使用了超时事件分支来处理这些判断,即如果超时时间内没有其它事件发生
就执行超时事件里的判断程序。如下图所示:


使用这种方法的程序一般都将超时时间设置在 50-200ms 之间,这种方法
有一个缺点,就是超时一次以后,如果在超时时间内仍然没有事件发生,程序会
再一次执行超时事件的程序,然后再等 50-200ms 又执行一次超时事件的程序,
如此一直循环,这样似乎又回到单While 循环结构上去了——定时执行程序,只
不过单While 循环时,要执行的程序更多一点罢了。这里超时时间的设置也麻烦,
设置长了,前面板的控件就得不到及时更新,而且有可能二次其它事件之间的时
间间隔小于超时时间,这样根本不会执行到超时事件(好像有些参赛程序为了不
让连续发生二次事件,在发生第一次事件时就会禁用对应的控件,然后在超时事
件里面再启用这些控件,以此来防止二次事件在超时时间内连续发生);设置时
间短了,超时事件执行得太过频繁,显然也是没有必要,就像上图中超时时间设
置为 1ms 就是太短了一点。
有几个程序是没有使用超时事件来更新这些控件的,一种是直接将这些更新
控件禁用属性的程序放到循环里面事件结构外面:


这种方法是在下一次事件发生之前都更新一次控件的禁用属性,这个方法用
在这里也是可以的,因为程序中刚好每次事件发生后都必须更新控件的属性的,
但在其它程序中,未必就是每次事件后都需要执行这些判断程序。
还有一种方法是使用“值改变(信号)”来动态触发事件,从而进行前面板
的更新的:   


当按下“Change”或其它按钮时,先执行对应的程序,最后通过“值改变(信
号)”来动态触发“Update”事件,从而更新前面板的“Tip”。这种方法就完全
没有使用超时事件时会不断更新前面板控件禁用属性的缺点,响应事件后,如果
需要更新前面板的“Tip”,就动态触发更新事件分支来执行就可以了,减少了不
必要的更新。
还有一种方法,没有在这次的参赛程序中发现,也是利用超时事件,但并不
是简单设置一个超时时间。
从前面的分析可以看到,使用超时事件来更新前面板的唯一缺点就是会带来
没必要的更新,有没有什么办法可以让超时事件有时候运行有时候又不运行呢?
我们可能会联想到超时时间设置为-1 时就是表示永远不执行超时事件,那么有
没有什么方法可以让超时时间一会是-1,一会是几十毫秒呢?由于事件结构是在
循环中运行,而很多程序也使用了移位寄存器,因此就可以通过移位寄存器来实
现:


程序开始运行时,将超时时间的移位寄存器初始化为-1,表示不需要更新前
面板,然后在响应“投币”事件时,将移位寄存器设置为 0,表示在需要马上执
行超时事件分支,更新前面板,移位寄存器将这个 0 传递到下一次循环中,此时
其它事件来不及发生,程序马上就执行超时事件,更新前面板;超时事件里面,
因为刚更新了一次前面板,所以又将超时时间设置为-1,下次循环时因为超时时
间为-1,所以不产生超时事件,此时等待其它事件发生。
这种方法就保证只有在需要的时候才更新前面板,而且将超时时间设置为
0,保证了程序会先执行超时事件分支,然后才会响应其它事件,鼠标双击“投
币”按钮的动作,希望能连续二次触发投币事件而中间不执行超时事件是不可能
的,因为鼠标的双击速度至少在 10ms 以上,就算有设置鼠标移动的事件源,然
后在响应一次鼠标移动事件分支里面将超时时间设置为 0,鼠标快速移动也没办
法连接二次触发鼠标移动的事件,也是按鼠标移动事件-超时事件-鼠标移动事件
-超时事件…这样的顺序触发。
另外还有一种方法是使用用于动态注册事件来实现的。在数据满足某条件
时,注册对应的用户事件,让程序响应这个事件,在用户事件分支里面更新控件
的属性,最后注销这个用户事件,后之不再被触发,,其原理也跟用“值改变(信
号)”的属性节点来动态触发更新事件是一样的,但它的可扩展性更强一点,因
为会有更多的事件可以自由被动态注册,缺点就是要学习更复杂一点的动态注册
事件。
后面这几种方法在性能上区别不大,最终使用哪一种,可能还是根据自己的习惯、风格来决定

了解更多labview事件结构请进入:http://bbs.elecfans.com/topic-labviewevent.html

逻辑、细节都很重要哇~~

小编辛苦,学习了

谢谢分享

辛苦了

谢谢

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top