VB.NET Timer异常:blocktimers遍历全部Timer但releasetimers仅遍历部分
问题分析与解决方案
首先看你的代码,问题出在**blocktimers()里数组的处理逻辑错误**,导致carray数组没有正确保存所有需要恢复的Timer,还混入了空元素,这就是为什么releasetimers()遍历到Nothing的原因。
具体问题点
i变量初始值默认为0,但循环中没有递增,每次符合条件的Timer都会覆盖carray(0),后续的ReDim操作只会增加数组长度,但实际有效元素只有最后一个符合条件的Timer,剩下的都是空值。- 每次执行
ReDim Preserve carray(i + 1)会让数组长度比实际需要保存的Timer数量多1,最后一个元素必然是Nothing。
修正后的代码
首先确保carray是模块级的Timer()数组(在类或模块的声明部分定义):
Private carray() As Timer
然后修改blocktimers()方法:
'Block timers Private Sub blocktimers() Dim i As Integer = -1 '初始化为-1,第一次递增后对应索引0 '先清空数组,避免之前的残留数据干扰 ReDim carray(-1) For Each c As Component In Me.components.Components If TypeOf c Is Timer Then Dim t As Timer = DirectCast(c, Timer) If t.Enabled And t.Interval <> 100 Then i += 1 ReDim Preserve carray(i) '仅扩展到当前需要的索引 carray(i) = t t.Stop() End If End If Next End Sub
再优化releasetimers()方法:
'Release timers Private Sub releasetimers() '先判断数组是否有效,避免空数组遍历报错 If carray Is Nothing OrElse UBound(carray) < 0 Then Exit Sub For Each c As Timer In carray If c IsNot Nothing Then c.Start() End If Next '清空数组释放资源(可选,根据业务需求决定) ReDim carray(-1) End Sub
关键改进点
- 初始化
i为-1,每次找到符合条件的Timer时先递增i,再调整数组大小,确保每个元素都对应一个有效的Timer。 - 每次
ReDim Preserve只扩展到当前索引i,不会生成多余的空元素。 - 在
blocktimers()开头清空数组,避免之前操作的旧数据残留。 - 在
releasetimers()开头增加数组有效性判断,避免空数组遍历的问题,结束后可清空数组释放内存。
这样修改后,blocktimers()会正确保存所有需要停止的Timer,releasetimers()也能遍历到所有有效的Timer,不会再出现Nothing的情况。
内容的提问来源于stack exchange,提问作者Adrian Hernando Solanas
相关产品推荐
相关产品推荐

