表单加载并显示

时间:2017-01-12 18:29:41

标签: vb.net timer nullreferenceexception

我的申请工作到今天几个月。它每天开始多次,由几个不同的人和计算机使用 - 所有这些都没有任何问题。今天我收到日志,简单的异常连接到未初始化的计时器。

异常

Type = System.NullReferenceException
Message = Object reference not set to an instance of an object.
TargetSite = Void StartTimer()
StackTrace = at QMS.frmStart_Main.StartTimer() in frmStart_Main.vb:line 64
at QMS.frmStart_Main.frmStart_Main_Shown(Object sender, EventArgs e) in frmStart_Main.vb:line 124
at System.Windows.Forms.Form.OnShown(EventArgs e)
...

请不要开始输入答案......:)

代码

frmStart_Main类的主管有一些私有变量,包括Timer initilization:

Public Class frmStart_Main
    Implements IMessageFilter

    Private WithEvents t As New Timer() With {.Interval = 1000}

    ' May be not relevant to my problem but I prefer to show that it exists here as they are part of one of the methods described later on...
    Private formIsClosing As Boolean = False
    Private _timeToAutoClose As Integer = 60
    Private _cycleStart As Integer = _timeToAutoClose
    Private _cycleCurrent As Integer = _cycleStart

我的Prefilter Message方法可以相关。我在计时器启动之前稍后将MessageFilter添加到我的表单中。这个方法里面的计时器没问题。

<DebuggerStepThrough>
Public Function PreFilterMessage(ByRef m As Message) As Boolean Implements IMessageFilter.PreFilterMessage
    If (m.Msg >= &H100 And m.Msg <= &H109) Or (m.Msg >= &H200 And m.Msg <= &H20E) Then
        t.Stop()
        t.Start()
        _cycleStart = _timeToAutoClose
        _cycleCurrent = _cycleStart
        timerTick(Nothing, Nothing)
    End If
    Return False
End Function

当加载表单时,我什么都没有连接到计时器

Private Sub frm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    ' Unrelated stuff here, nothing connected to timer
End Sub

当显示表单时,我阻止&#39;关闭&#39;按钮,在后台启动一些长时间运行的任务,完成任务后,我调用启动计时器的方法。

Private Sub frm_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown

        cmdClose.Disable

        bgworker = New BackgroundWorker With {.WorkerReportsProgress = True, .WorkerSupportsCancellation = True}
        AddHandler bgworker.RunWorkerCompleted, AddressOf bgworker_RunWorkerCompleted
        AddHandler bgworker.ProgressChanged, AddressOf bgworker_ProgressChanged
        AddHandler bgworker.DoWork, AddressOf StartUpCheck
        bgworker.RunWorkerAsync()

        While bgworker.IsBusy
            Application.DoEvents()
        End While

        Call StartTimer() 

    End Sub

最后引发异常的StartTimer方法代码:

Private Sub StartTimer()
    Application.AddMessageFilter(Me)
    t.Start() ' <===== here we have an exception! Line 64.
End Sub

我提前道歉很长时间,可能不是代码的相关部分。

问题

那么,你能解释一下为什么这个应用程序有数千次工作,今天有一次它在这里引发了异常吗?以及如何重写计时器代码的关键部分以避免将来使用它?

更新1

当表格关闭时,我设置了标志formIsClosing

Private Sub frm_Closing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing

    formIsClosing = True
    Call StopTimer()

End Sub

StopTimer方法是:

Public Sub StopTimer()
    Application.RemoveMessageFilter(Me)
    If t IsNot Nothing Then
        t.Dispose()
        t = Nothing
    End If
End Sub

更新2

我发现我还需要发布我的t.tick方法来完成故事。

Private Sub timerTick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles t.Tick
    If Not formIsClosing Then
        If _cycleCurrent > 0 Then
            Me.pbTimeToClose.Maximum = _cycleStart
            Me.pbTimeToClose.Value = _cycleCurrent
            _cycleCurrent -= 1

            ' Unrelated stuff here...

        Else

            Call My.Application.DisposeAllFormsExceptMe(Me)
            Me.Close()

        End If
    End If
End Sub

0 个答案:

没有答案