Backgroundworker线程导致UI挂起

时间:2010-08-29 22:42:47

标签: .net vb.net backgroundworker

我有一个后台工作程序正在检查远程服务器上的四个服务的状态。 这是在定时器(5秒)上设置,如下所示。出于某种原因,它挂起了UI线程,导致应用程序每次勾选“锁定”,我无法理解为什么?!

Private Sub ServiceTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ServiceTimer.Tick

    _ServiceBGWorker = New System.ComponentModel.BackgroundWorker()
    _ServiceBGWorker.WorkerSupportsCancellation = False
    _ServiceBGWorker.WorkerReportsProgress = False
    AddHandler _ServiceBGWorker.DoWork, New DoWorkEventHandler(AddressOf Me.CheckService)

    _ServiceBGWorker.RunWorkerAsync()
    While _ServiceBGWorker.IsBusy
        Application.DoEvents()
    End While
End Sub

Private Sub CheckService(ByVal sender As Object, ByVal e As DoWorkEventArgs)

    If CheckService("Service 3.5") = ServiceControllerStatus.Stopped Then
        PBServiceStatus35.Image = ImgStopIcon
    ElseIf CheckService("Service 3.5") = ServiceControllerStatus.Running Then

        PBServiceStatus35.Image = ImgGoIcon
    Else
        PBServiceStatus35.Image = ImgHelpIcon
    End If

    If CheckService("Service 3.6") = ServiceControllerStatus.Stopped Then

        PBServiceStatus36.Image = ImgStopIcon
    ElseIf CheckService("Service 3.6") = ServiceControllerStatus.Running Then

        PBServiceStatus36.Image = ImgGoIcon
    Else
        PBServiceStatus36.Image = ImgHelpIcon
    End If

    If CheckService("Service 3.7") = ServiceControllerStatus.Stopped Then
        PBServiceStatus37.Image = ImgStopIcon
    ElseIf CheckService("Service 3.7") = ServiceControllerStatus.Running Then
        PBServiceStatus37.Image = ImgGoIcon
    Else
        PBServiceStatus37.Image = ImgHelpIcon
    End If

    If CheckService("Service 4.0") = ServiceControllerStatus.Stopped Then
        PBServiceStatus40.Image = ImgStopIcon
    ElseIf CheckService("Service 4.0") = ServiceControllerStatus.Running Then
        PBServiceStatus40.Image = ImgGoIcon
    Else
        PBServiceStatus40.Image = ImgHelpIcon
    End If
End Sub


Private Function CheckService(ByVal ServiceName As String)
    Dim myController = New ServiceController(ServiceName)
    myController.MachineName = SQLServerName
    myController.Refresh()
    Return myController.Status
End Function

2 个答案:

答案 0 :(得分:2)

查看MSDN Background Worker Class 文档并不会有什么坏处。注释

  

您必须小心不要操作DoWork事件处理程序中的任何用户界面对象。而是通过ProgressChanged和RunWorkerCompleted事件与用户界面进行通信。

因此,不要在DoWork处理程序中操作图片框,而是使用上述处理程序。我写了两个简单的表单并从DoWork处理程序加载一个表单,当从DoWork加载表单时,表单和UI无限期挂起,但是从其他表单中正确响应。

答案 1 :(得分:1)

这个while循环是完全没必要的:

While _ServiceBGWorker.IsBusy
    Application.DoEvents()
End While

我不知道它怎么会在这里引起你的直接问题,但你可能会尝试没有。

在相关的说明中,添加一个Completed处理程序并检查e.Error状态是个好主意。也许有些东西会抛出异常。使用您当前的代码,您永远不会知道。