异步控制事件的更新表单

时间:2012-01-31 16:41:55

标签: vb.net winforms

几周前,我为ServiceController控件编写了一个包装器,以增强和简化基本的ServiceController。我做的一个更改是使用System.Threading.Timer对象添加监视组件。在任何状态更改时,都会向父类引发一个事件。实际的监控工作正常,但是当事件在主窗体中处理时,我的程序突然结束 - 没有异常,没有警告,它就退出了。这是控件的骨架版本:

Public Class EnhancedServiceController
    Inherits ServiceController

    Public Event Stopped(ByVal sender As Object, ByVal e As System.EventArgs)
    Public Event Started(ByVal sender As Object, ByVal e As System.EventArgs)

    Private _LastStatus As System.ServiceProcess.ServiceControllerStatus

    Private serviceCheckTimer as System.Threading.Timer
    Private serviceCheckTimerDelegate as System.Threading.TimerCallback

    ...

    Private Sub StartMonitor()
        MyBase.Refresh()
        _LastStatus = MyBase.Status
        serviceCheckTimerDelegate = New System.Threading.TimerCallback(AddressOf CheckStatus)
        serviceCheckTimer = New System.Threading.Timer(serviceCheckTimerDelegate, Nothing, 0, 60*1000)
    End Sub

    Private Sub CheckStatus()
        MyBase.Refresh()
        Dim s As Integer = MyBase.Status
        Select Case s
            Case ServiceControllerStatus.Stopped
                If Not s = _LastStatus Then
                    RaiseEvent Stopped(Me, New System.EventArgs)
                End If
            Case ServiceControllerStatus.Running
                If Not s = _LastStatus Then
                    RaiseEvent Started(Me, New System.EventArgs)
                End If
        End Select
        _LastStatus = s
    End Sub

End Class

形式:

Public Class Form1
    Private Sub ServiceStarted(ByVal sender As Object, ByVal e As System.EventArgs) Handles ESC.Started
        Me.TextBox1.Text = "STARTED"
    End Sub

    Private Sub ServiceStopped(ByVal sender As Object, ByVal e As System.EventArgs) Handles ESC.Stopped
        Me.TextBox1.Text = "STOPPED"
    End Sub
End Class

如果我不得不猜测,我会说有某种线程问题,但我不确定如何在表单中处理它。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

如果它是一个线程问题,那么您可能正在尝试从非UI线程更新UI。

所以这样的事情应该解决......

Private Delegate Sub UpdateTextBoxDelegate(byval tText as String)

Private Sub UpdateTextBox(byval tText As String)
    If Me.InvokeRequired Then
        Me.Invoke(New UpdateTextBoxDelegate(AddressOf UpdateTextBox), tText)
        Exit Sub
    End If

    TextBox1.Text = tText
End Sub

Private Sub ServiceStarted(ByVal sender As Object, ByVal e As System.EventArgs) Handles ESC.Started 
    UpdateTextBox ("STARTED")
End Sub 

Private Sub ServiceStopped(ByVal sender As Object, ByVal e As System.EventArgs) Handles ESC.Stopped
    UpdateTextBox("STOPPED")
End Sub