You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

关键改进点

  1. 初始化i为-1,每次找到符合条件的Timer时先递增i,再调整数组大小,确保每个元素都对应一个有效的Timer。
  2. 每次ReDim Preserve只扩展到当前索引i,不会生成多余的空元素。
  3. 在blocktimers()开头清空数组,避免之前操作的旧数据残留。
  4. 在releasetimers()开头增加数组有效性判断,避免空数组遍历的问题,结束后可清空数组释放内存。

这样修改后,blocktimers()会正确保存所有需要停止的Timer,releasetimers()也能遍历到所有有效的Timer,不会再出现Nothing的情况。

内容的提问来源于stack exchange,提问作者Adrian Hernando Solanas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:12:12